我碰巧关注传递给System.Threading.Thread.Sleep(int millisecondsTimeout)
的参数的intellisense工具提示,说"(...)指定System.Threading.Timeout.Infinite来阻止线程无限期&#34 ;.我很感兴趣。
我可以理解为什么在可能无限循环中可能包含短的非活动延迟,因此当需要在休眠线程中没有立即操作时,会向其他正在执行的线程产生处理能力,尽管我通常更喜欢用{{1}实现这样的延迟如果我发信号通知线程从另一个线程优雅地结束执行,我就可以避免等待完全休眠延迟。
但我无法确定何时可能需要无限期地暂停某个帖子,而且就我所知,只能通过一个相当不合理的EventWaitHandler
/ Thread.Abort()
对中断
那么我可能想要无限期暂停一个线程的工作场景是什么?
答案 0 :(得分:10)
这是一个非常漫长的故事,我不得不挥手让我觉得可以理解。大多数程序员认为Thread.Sleep()将线程置于休眠状态并阻止它执行任何代码。这不准确。 Thread.Sleep(Infinite)等同于Application.Run()。开个玩笑。
这在现实生活中并不经常发生,它主要与自定义托管方案相关。获取代码以在特定线程上运行通常是处理非线程安全的代码以及Application.Run()存在的主要原因的重要特性。但是Windows暴露了另一种在更低级别上做的方式,其基础api是QueueUserAPC()。此函数的.NET模拟是BeginInvoke()。
这需要线程进行协作,就像调用Application.Run()时一样。线程必须处于“可警告的等待状态”,执行可以中断的阻塞功能。 CLR本身不执行睡眠,它将作业传递给CLR host。大多数主机只执行SleepEx(),为bAlertable参数传递TRUE。该线程现在处于执行QueueUserAPC()发布的任何请求的状态。就像在Application.Run()调度程序循环中主动执行它一样。
框架中根本没有公开内核功能。这种代码很难做到正确,重新入侵的错误非常讨厌。由于大多数被Application.DoEvents()或者位置不佳的MessageBox.Show()所困扰的程序员都可以证明。但是,它是自定义主机方案中的有效方案。主机可以使用此机制获取在特定线程上运行的C#代码。所以有可能通过Infinite,因为设计师不想故意禁用这种情况。如果主持人作者可以做到这一点,那么他们会让你知道。我不知道一个实际的例子。
更实际的是,您每天都会使用此功能。它是实现System.Threading.Timer和System.Timers.Timer的方式。通过CLR中的一个线程完成,该线程在您使用任何计时器时立即启动,它的核心使用SleepEx(INFINITE, TRUE)。
答案 1 :(得分:2)
您可以使用.Interrupt()
唤醒一个休眠线程(在调用ThreadInterruptedException
的代码中导致.Sleep()
,这可以被捕获和处理),所以这提供了一个机制来说“睡觉直到有人刺激你”。我并不是说它必然是最好的机制,但是:它可能对你有用。