为什么 Thread.Sleep 如此有害 [英] Why is Thread.Sleep so harmful
问题描述
我经常看到它提到不应该使用Thread.Sleep();
,但我不明白为什么会这样.如果 Thread.Sleep();
会引起麻烦,是否有其他安全的替代解决方案具有相同的结果?
I often see it mentioned that Thread.Sleep();
should not be used, but I can't understand why this is so. If Thread.Sleep();
can cause trouble, are there any alternative solutions with the same result that would be safe?
例如
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
的问题是 在这里解释得很简洁:
Thread.Sleep
有它的用途:在 MTA 线程上测试/调试时模拟冗长的操作.在 .NET 中没有其他理由使用它.
Thread.Sleep
has its use: simulating lengthy operations while testing/debugging on an MTA thread. In .NET there's no other reason to use it.
Thread.Sleep(n)
表示阻塞当前线程至少数n
中可能出现的时间片(或线程量)毫秒.不同版本/类型的时间片长度不同Windows 和不同的处理器,一般范围从 15 到 30毫秒.这意味着线程几乎可以保证阻塞超过 n
毫秒.你的线程的可能性在 n
毫秒后重新唤醒几乎是不可能的不可能可以.因此,Thread.Sleep
对计时毫无意义.
Thread.Sleep(n)
means block the current thread for at least the number
of timeslices (or thread quantums) that can occur within n
milliseconds.
The length of a timeslice is different on different versions/types of
Windows and different processors and generally ranges from 15 to 30
milliseconds. This means the thread is almost guaranteed to block for
more than n
milliseconds. The likelihood that your thread will
re-awaken exactly after n
milliseconds is about as impossible as
impossible can be. So, Thread.Sleep
is pointless for timing.
线程是一种有限的资源,它们需要大约 200,000 个周期创建和销毁大约 100,000 个周期.默认情况下,他们为其堆栈保留 1 兆字节的虚拟内存并使用 2,000-8,000每个上下文切换的周期.这使得任何等待线程成为巨大浪费.
Threads are a limited resource, they take approximately 200,000 cycles to create and about 100,000 cycles to destroy. By default they reserve 1 megabyte of virtual memory for its stack and use 2,000-8,000 cycles for each context switch. This makes any waiting thread a huge waste.
首选方案:WaitHandles
最容易犯的错误是将 Thread.Sleep
与 while 构造一起使用(演示和回答, 不错的博客入口)
The most-made-mistake is using Thread.Sleep
with a while-construct (demo and answer, nice blog-entry)
我想加强我的回答:
I would like to enhance my answer:
我们有两个不同的用例:
We have 2 different use-cases:
我们在等待,因为我们知道我们应该继续的特定时间跨度(使用
Thread.Sleep
、System.Threading.Timer
或类似的)
我们正在等待,因为某些情况在一段时间内发生了变化......关键字是/是一段时间!如果条件检查在我们的代码域中,我们应该使用 WaitHandles - 否则外部组件应该提供某种钩子......如果没有,它的设计很糟糕!
We are waiting because some condition changes some time ... keyword(s) is/are some time! if the condition-check is in our code-domain, we should use WaitHandles - otherwise the external component should provide some kind of hooks ... if it doesn't its design is bad!
我的回答主要涵盖用例 2
My answer mainly covers use-case 2
这篇关于为什么 Thread.Sleep 如此有害的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!