为什么 Thread.Sleep 如此有害 [英] Why is Thread.Sleep so harmful

查看:36
本文介绍了为什么 Thread.Sleep 如此有害的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常看到它提到不应该使用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:

  1. 我们在等待,因为我们知道我们应该继续的特定时间跨度(使用 Thread.SleepSystem.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆