gpt4 book ai didi

c# - 使用 Thread.Sleep 等待的替代方法

转载 作者:可可西里 更新时间:2023-11-01 03:01:31 26 4
gpt4 key购买 nike

首先,我问的不是与C# - Alternative to Thread.Sleep? 相同的问题, 或 Alternative to Thread.Sleep in C#? .我认为我没有错误地使用它,并且在特定情况下需要一个真正的替代品。

在代码分析运行期间,我看到了一个令人惊讶的违规行为:

Usage of Thread.Sleep() is a sign of flawed design.

此违规导致 Peter Richie's article关于为什么这构成糟糕的设计。

我们都知道线程创建是昂贵的,线程中的阻塞意味着对池的争用。我们也知道每个线程都会分配一个 meg 的内存,所以它应该有一个短的生命周期,阻塞在 UI 上是邪恶的,使用 sleep 计时是不可靠的等等等等。这让我明白了,如果你真的需要执行 sleep ,如果不是 Thread.Sleep,你应该使用什么?

Peter 继续提到,零 sleep 是 Thread.Sleep 的唯一正确使用,它有效地放弃了线程的时间片并允许其他线程进行处理。更可怕的是,这只是因为非托管线程的限制,如果在 CLR 中重新实现,将会产生在您的应用程序中使用 Thread.Sleep 的副作用。事实上,所有关于常见错误用法的要点都是错误用法的好例子。

我在使用 Thread.Sleep 非常成功的生产代码中有以下情况:

  • 等待操作系统放弃文件锁(捕获文件锁问题,稍等,重试,稍后放弃)。
  • 杀死一个进程并等待它不再出现在进程列表中(杀死它,检查它是否正在运行,等待一秒钟,检查它是否仍在运行,强制关闭)。
  • 等待复制缓冲区刷新(检查文件大小,尝试访问它,等待,检查大小是否已更改)。

如果在这些情况下不使用 Thread.Sleep,我还有哪些其他选择?紧密循环往往会使事情变得更糟,我不认为这会使它的使用成为“设计缺陷”,尤其是因为 UI 上没有任何内容,仅在后台线程中。在多线程环境中等待其他事情只是软件的本质,外部因素会影响您的代码,有时您需要等待...

最佳答案

WaitHandle type 和派生类型提供了一种事件驱动的机制来等待与操作系统的联系。例如,当您有一个 Task<T> task然后您通过访问 task.Result 等待结果, 内部实现不使用 Thread.Sleep 进行轮询之间的调用。它使用 WaitHandle -派生类型进行等待和同步。

有时,基于轮询的方法是必要的,就像您在项目符号列表中给出的一些示例中那样,但通常您可以改用事件驱动的方法。不是那个Thread.Sleep 总是不好 - 只是它经常被误用

It is just the nature of software to wait for other things in a multi-threaded environment with external factors affecting your code, sometimes you need to wait...

等待 没问题。 等待轮询通常不是 (*)。如果有任何方法可以使用事件驱动等待,您通常应该努力使用它。

我不太清楚你要问的是什么,所以我不会详细说明。如果您发表评论,我可以扩展我的答案。


(*) waiting with polling 不好的理论原因如下:

假设我有这样的代码:

//START
Begin();
while (!Done())
Thread.Sleep(D);
//STOP

Begin()开始一些操作。 Done()返回 true表示操作已经完成。假设这将在大约 T 之后发生时间。然后:

  • 线程唤醒并检查条件(调用 Done() )T/D
  • START开始的持续时间至 STOP包括预期的 D/2纯粹是因为 Thread.Sleep

D 的值是多少?你应该选择吗?随着你增加D , 预期持续时间形式 STARTSTOP线性增加。随着你减少D ,(绑定(bind))迭代次数增加为 1/D .这两个都不好,找到合适的D是有问题的。

现在将其与事件驱动的等待进行比较:

//START
Begin();
WaitDone();
//STOP

理论上只要WaitDone()不知何故神奇地等到操作完成但不再,在waiting with polling 案例中发现的两个问题都消失了:这个线程等待的时间恰到好处- 不多也不少!

重申我开始的观点:在 .NET 中,WaitHandle类和派生类型促进了这种方法。

关于c# - 使用 Thread.Sleep 等待的替代方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16992859/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com