为啥 Thread.Sleep 不在秒表中注册?

Posted

技术标签:

【中文标题】为啥 Thread.Sleep 不在秒表中注册?【英文标题】:Why doesn't Thread.Sleep register in Stopwatch?为什么 Thread.Sleep 不在秒表中注册? 【发布时间】:2021-11-21 21:00:23 【问题描述】:

我有以下程序:

open System.Diagnostics
open System.Threading

[<EntryPoint>]
let main _ =
    let timer = Stopwatch ()
    printfn "begin"
    timer.Start ()
    Thread.Sleep 5000
    timer.Stop ()
    printfn "end"
    printfn "%i ms" timer.Elapsed.Milliseconds
    0

我希望它能够打印 5000 毫秒或更多的经过时间。它确实在打印“开始”和“结束”之间暂停了大约 5 秒。但它只打印“3 ms”左右。为什么Stopwatch不计算睡眠时间?

【问题讨论】:

我相信这是因为您的计时器在同一个线程上运行。那么当你的线程休眠时,计时器会停止吗? 感谢@Selthien 的建议,但事实证明这是一个愚蠢的错误,如答案中所述。实在是太愚蠢了,我会在一段时间后删除这个问题。 不,请不要删除问题@CarbonFlambe。这很愚蠢,是的,但也很常见:许多人出于同样的原因犯了同样的错误——因为属性名称不是很直观。如果你留下这个问题,它会在未来帮助其他人。 【参考方案1】:

这是因为 Elapsed 属性返回一个 TimeSpan,而该 TimeSpan 的 Milliseconds 属性非常小。如果您使用 ElapsedMilliseconds 属性,您应该会看到一个不错的值。

[编辑] 你也可以使用 timer.Elapsed.TotalMilliseconds,(它是一个浮点数,而不是一个整数)。

【讨论】:

是的,Elapsed 只返回一个组件。这是 5 秒加上 3 毫秒。

以上是关于为啥 Thread.Sleep 不在秒表中注册?的主要内容,如果未能解决你的问题,请参考以下文章

如果 Task.Delay 优于 Thread.Sleep,为啥本书中的示例使用 Thread.Sleep?

为啥 Thread.Sleep 如此有害

为啥我必须将每个 Thread.sleep() 调用包装在 try/catch 语句中? [复制]

为啥 Thread.sleep 不好用

如果我不在 WinForms 上使用 Thread.Sleep,BackgroundWorker 将不起作用

为啥要放弃使用Thread.Sleep