一尘不染

为什么Thread.Sleep如此有害

c#

我经常看到它提到Thread.Sleep();不应使用,但我不明白为什么会这样。如果Thread.Sleep();会引起麻烦,是否有其他相同结果的替代解决方案是安全的?

例如。

while(true)
{
    doSomework();
    i++;
    Thread.Sleep(5000);
}

另一个是:

while (true)
{
    string[] images = Directory.GetFiles(@"C:\Dir", "*.png");

    foreach (string image in images)
    {
        this.Invoke(() => this.Enabled = true);
        pictureBox1.Image = new Bitmap(image);
        Thread.Sleep(1000);
    }
}

阅读 1020

收藏
2020-05-19

共1个答案

一尘不染

与调用问题Thread.SleepARE
相当简洁解释在这里

Thread.Sleep它的用途:在MTA线程上测试/调试时模拟冗长的操作。在.NET中,没有其他理由使用它。

Thread.Sleep(n)表示将当前线程阻塞至少n
几毫秒内可能发生的时间片(或线程数量)。在Windows的不同版本/类型和不同的处理器上,时间片的长度是不同的,并且通常在15到30毫秒之间。这意味着几乎可以保证线程阻塞的时间超过n毫秒。n毫秒之后,线程将完全重新唤醒的可能性几乎是不可能的。
因此,Thread.Sleep计时是没有意义的

线程是有限的资源,它们大约需要200,000个周期来创建,而销毁大约100,000个周期。默认情况下,它们为其堆栈保留1
MB的虚拟内存,并为每个上下文切换使用2,000-8,000个周期。 这使得任何等待线程都是 巨大的 浪费。

首选解决方案:WaitHandles

最错误的做法是使用Thread.Sleepwhile构造(演示和答案不错的博客条目

编辑:
我想增强我的答案:

我们有2个不同的用例:

1.
我们正在等待,因为我们知道一个特定的时间跨度时,我们应该继续(使用Thread.SleepSystem.Threading.Timer或相似者)

  1. 我们正在等待,因为某些条件会改变一段时间…关键字会 持续一段时间 !如果条件检查在我们的代码域中,则应使用WaitHandles-
    否则,外部组件应提供某种类型的钩子……如果不是,则其设计不好!

我的回答主要涵盖用例2

2020-05-19