2011-03-29 100 views
3

很多时候,当我看到一些多线程代码时,我在代码中看到Thread.Sleep()语句。在多线程应用程序中使用Thread.Sleep的原因是什么?

我甚至没有崩溃,我试图找出问题,这样评价了大部分的多线程代码,并慢慢把它和最后一块时,我增加了一个像声明:

for (int i = 0; i < 1000000; ++i) 
    ++i; 

它没有崩溃。所以现在我把它取代Thread.Sleep(),它似乎工作。我无法轻易地将它发布到这里,但是正在使用Thread.Sleep()对于多线程应用程序是必需的吗?

他们的目的是什么?如果不使用会导致意想不到的结果吗?

编辑:顺便说一句我正在使用BackgroundWorker,只在那里实现我的东西,但不知道是什么原因造成的。虽然我使用的API是应用程序不是多线程的托管应用程序。因此,举例来说,我认为我不能一次在多个线程上调用它的API函数。不确定,但那是我的猜测。

+3

参见[Thread.sleep代码是一个设计不当的程序的标志(http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-睡眠是-A-签的-A-设计拙劣的-program.aspx)。 – Alex 2011-03-29 18:29:14

回答

4

通常,Thread.Sleep表示设计不好。话虽这么说,它比100%的CPU核心时间更好,这正是上面的for循环所做的。

更好的选项通常是使用WaitHandle(如ManualResetEvent)在发生“事件”(这是延迟原因)时触发线程执行的继续。另外,在很多情况下,使用Timer也可以。

+0

谢谢里德,你可以用BackgroundWorker做这些吗? – 2011-03-29 18:35:27

+0

@Joan:WaitHandles和BW一起工作良好 - BW仍然只是使用ThreadPool线程来完成工作,所以任何同步选项仍然有效。 – 2011-03-29 18:36:23

+0

谢谢里德,这很有道理。但最终这种拖延是无法避免的,对吧? – 2011-03-29 19:02:18

3

Thread.Sleep(1)允许切换到执行另一个线程。所以如果你有更多的线程比核心/处理器,并且你知道“现在我在这个线程中做了很多工作,下一步工作可以稍后完成”,你可以拨打Thread.Sleep(1),并允许另一个线程比本机更快地完成一些工作切换器将“暂停”当前执行的线程。

+1

'Thread.Sleep(0)'应该具有相同的效果,而不会阻塞整个ms。 – Davy8 2011-03-29 18:40:31

+0

@ Davy8你是对的。 – TcKs 2011-03-30 09:11:39

1

试试这个:编写一个启动100个线程的程序,并将每个线程放到for循环中,如上所述。然后编写另一个启动100个线程并使用Thread.Sleep代替。

运行它们并比较CPU使用率。你会看到这一点。 =)

1

Thread.Sleep()只是简单地导致正在执行的线程暂停指定的持续时间。

我见过很多开发人员使用Thread.Sleep(),因为他们不太可能处理依赖线程的连接。他们只是使用Thread.Sleep()来强制一个线程等待一段时间,直到认为他们的其他线程已经完成并且他们的数据可用。

如果你有两个线程需要彼此等待以继续进行处理,那么你应该真的使用.NET中内置的机制来处理类似的情况(即ManualResetEvent等)

1

Thread.Sleep()可以在某些情况下使用,例如。看门狗线程。

然而在你的情况下,它可能不是其他人指出的最佳解决方案。

没有代码示例,很难说,但根据您的描述,我认为这不是Thread.Sleep()的问题。我怀疑你可能正在遭受竞争状态 - 这通常就是为什么你会遇到“随机”的错误行为,甚至是多线程代码中的“随机”崩溃 - 这似乎是你正在经历的。

无论出于何种原因,您的for-loop可能会导致竞争条件的微妙关键时刻不经常发生,但它不会解决根本原因。在进行多线程编程时有许多缺陷需要注意,如果您想避免这些,我只能建议您阅读该主题。

我会建议你阅读http://www.amazon.com/Concurrent-Programming-Windows-Joe-Duffy/dp/032143482X