为什么 Thread.Sleep 如此有害

2023-12-12

我经常看到有人提到Thread.Sleep();不应该使用,但我不明白为什么会这样。如果Thread.Sleep();可能会造成麻烦,是否有任何具有相同结果且安全的替代解决方案?

eg.

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);
    }
}

打电话的问题Thread.Sleep are 这里解释得很简洁:

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

Thread.Sleep(n)表示阻塞当前线程至少 number 可能发生在的时间片(或线程量子)n毫秒。 时间片的长度在不同版本/类型上是不同的 Windows 和不同的处理器,一般范围为 15 到 30 毫秒。这意味着线程几乎肯定会阻塞 多于n毫秒。您的线程的可能性 恰好在之后重新醒来n毫秒几乎是不可能的 不可能可以。So, Thread.Sleep对于时间安排来说毫无意义.

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

首选解决方案:等待句柄

最常犯的错误是使用Thread.Sleep使用 while 构造 (演示及解答, 不错的博客条目)

EDIT:
我想补充一下我的答案:

我们有 2 个不同的用例:

  1. 我们等待是因为我们知道 我们应该继续的具体时间跨度(使用Thread.Sleep, System.Threading.Timer或类似的)

  2. 我们正在等待,因为某些情况有时会发生变化...... 关键字是某个时间!如果条件检查在我们的代码域中,我们 应该使用 WaitHandles - 否则外部组件应该 提供某种挂钩……如果没有,它的设计就很糟糕!

我的回答主要涵盖用例2

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Thread.Sleep 如此有害 的相关文章

随机推荐