有没有办法唤醒正在睡觉的线程?
C# 有没有办法唤醒休眠线程?那么,是否让它休眠很长时间并在需要处理工作时唤醒它?
Is there a way to wake a sleeping thread in C#? So, have it sleep for either a long time and wake it when you want work processed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
AutoResetEvent
对象(或另一个WaitHandle
实现)可用于休眠,直到收到另一个线程的信号:An
AutoResetEvent
object (or anotherWaitHandle
implementation) can be used to sleep until a signal from another thread is received:如果您的线程处于对
Sleep
的调用中,那么(通常)没有办法唤醒它。 (我知道的唯一例外是Java,如果其他线程调用thread.interrupt()
,它允许提前结束睡眠。)您正在讨论的模式似乎调用对于事件:线程包含一个循环,在循环顶部等待事件触发。如果当前未设置该事件,则该线程将“休眠”,直到其他线程触发该事件。此时,休眠线程被唤醒并继续其工作,直到下一次循环时它休眠以等待另一个事件。
If your thread is inside a call to
Sleep
, then there isn't (usually) a way to wake it up. (The only exception I'm aware of is Java, which allows a sleep to be ended early if some other thread callsthread.interrupt()
.)The pattern that you're talking about seems to call for an event: the thread contains a loop, at the top of which it waits for an event to fire. If the event is currently unset, then the thread "sleeps" until some other thread fires the event. At that point, the sleeping thread wakes up and continues its work, until the next time through the loop when it sleeps to wait for another event.
实际上有一个 线程。 C# 中的 Interrupt() 方法。
虽然接受的答案确实描述了您在您的情况下可能需要的良好模式,但我来到这个问题寻找 Thread.Interrupt 所以我把它放在这里。
There is actually a thread.Interrupt() method in C#.
While the accepted answer does describes a good pattern that you probably want in your case, I came to this question looking for Thread.Interrupt so I am putting it here.
最好的解决方案是将
Task
对象与默认的TaskFactory
一起使用。这个 API(在 .NET 4.0 中引入)使用带有工作窃取队列和所有奇特东西的线程池。如果 .NET 4.0 不可用,则使用 ThreadPool,它具有内置工作队列(它执行一些池平衡,但与 4.0 线程池不在同一范围内)。
如果您确实必须自己动手,那么我推荐使用
BlockingCollection
,它是 .NET 4.0 中添加的阻塞消费者/生产者队列。如果您确实必须自己执行此操作并且无法使用 .NET 4.0,那么您可以使用
ManualResetEvent
或AutoResetEvent 以及受
锁
保护的工作队列。The best solution would be to use
Task
objects with the defaultTaskFactory
. This API (introduced in .NET 4.0) uses a pool of threads with work-stealing queues and all that fancy stuff.If .NET 4.0 isn't available, then use the
ThreadPool
, which has a built-in work queue (which does some pool balancing but not on the same scope as the 4.0 thread pool).If you really must do it yourself, then I recommend a
BlockingCollection<T>
, which is a blocking consumer/producer queue added in .NET 4.0.If you really must do it yourself and can't use .NET 4.0, then you can use a
ManualResetEvent
orAutoResetEvent
along with alock
-protected queue of work.扩展 Wim 的答案,您还可以指定
WaitHandle.WaitOne()
调用的超时。因此您可以使用 Thread.Sleep() 来代替。CancellationToken
结构为您提供了一个,这样您就可以像这样发出任务信号:Expanding Wim's answer you can also specify a timeout for the
WaitHandle.WaitOne()
call. So you can use instead ofThread.Sleep()
.CancellationToken
struct provides you with one so you can signal your tasks like this:会这个 线程帮助? C# 具有用于线程事件处理的良好的功能。我的大部分工作都是在 Python 中完成的,但 C# 似乎有可靠的线程阻塞库。
Would this thread help? C# has good functionality for thread Event handling. I've done most of my work in Python, but C# seems to have solid libraries for thread blocking.
基于 Ilia 的建议:
并且...
这个解决方案很粗糙,因为可能还有其他原因引发 ThreadInterruptedException 。
Based on Ilia's suggestion:
and...
This solution is crude, as there may be other reasons why the
ThreadInterruptedException
is thrown.