有没有办法唤醒睡眠线程?
Posted
技术标签:
【中文标题】有没有办法唤醒睡眠线程?【英文标题】:Is there a way to wake a sleeping thread? 【发布时间】:2011-03-28 11:30:36 【问题描述】:有没有办法唤醒 C# 中的休眠线程?那么,让它休眠很长时间,然后在您想要处理工作时唤醒它?
【问题讨论】:
究竟是在什么环境下?我们真的需要更多关于您正在使用的平台和/或线程模型的信息才能有意义地回答这个问题。 这取决于你如何让它进入睡眠状态。 你肯定至少要告诉我们这个问题是关于什么编程语言的。 它是 C# - 我认为它可能与语言有关。 这是一个有用的帖子Safely wake and exit a sleeping C# thread without Thread.Abort()。 【参考方案1】:一个AutoResetEvent
对象(或另一个WaitHandle
实现)可用于休眠,直到收到来自另一个线程的信号:
// launch a calculation thread
var waitHandle = new AutoResetEvent(false);
int result;
var calculationThread = new Thread(
delegate
// this code will run on the calculation thread
result = FactorSomeLargeNumber();
waitHandle.Set();
);
calculationThread.Start();
// now that the other thread is launched, we can do something else.
DoOtherStuff();
// we've run out of other stuff to do, so sleep until calculation thread finishes
waitHandle.WaitOne();
【讨论】:
【参考方案2】:如果您的线程在对Sleep
的调用中,那么(通常)没有办法唤醒它。 (我知道的唯一例外是 Java,如果其他线程调用 thread.interrupt()
,它允许提前结束睡眠。)
您所说的模式似乎需要一个事件:线程包含一个循环,它在循环的顶部等待事件触发。如果事件当前未设置,则线程“休眠”直到某个其他线程触发该事件。此时,正在休眠的线程被唤醒并继续其工作,直到下一次通过循环休眠以等待另一个事件。
【讨论】:
【参考方案3】:C# 中实际上有一个thread.Interrupt() 方法。 虽然接受的答案确实描述了您可能想要的一个很好的模式,但我来这个问题是为了寻找 Thread.Interrupt 所以我把它放在这里。
【讨论】:
【参考方案4】:最好的解决方案是使用Task
对象和默认TaskFactory
。这个 API(在 .NET 4.0 中引入)使用一个线程池,带有工作窃取队列和所有花哨的东西。
如果 .NET 4.0 不可用,则使用 ThreadPool
,它有一个内置的工作队列(它会进行一些池平衡,但与 4.0 线程池不在同一范围内)。
如果你真的必须自己做,那么我推荐BlockingCollection<T>
,它是.NET 4.0 中添加的阻塞消费者/生产者队列。
如果你真的必须自己做并且不能使用.NET 4.0,那么你可以使用ManualResetEvent
或AutoResetEvent
以及@987654327 @-protected 工作队列。
【讨论】:
这没有回答问题“如何唤醒沉睡的踏板?”,我们如何通过Task
获得所需的功能?【参考方案5】:
扩展 Wim 的答案,您还可以为 WaitHandle.WaitOne()
调用指定超时。所以你可以用Thread.Sleep()
代替。 CancellationToken
struct 为您提供了一个,因此您可以像这样向您的任务发出信号:
string SleepAndWakeUp(string value,CancellationToken ct)
ct.WaitHandle.WaitOne(60000);
return value;
void Parent()
CancellationTokenSource cts = new CancellationTokenSource();
Task.Run(() => SleepAndWakeUp("Hello World!", cts.Token), cts.Token);
//Do some other work here
cts.Cancel(); //Wake up the asynch task
【讨论】:
【参考方案6】:this 线程有帮助吗? C# 有 good functionality 用于线程事件处理。我在 Python 中完成了大部分工作,但 C# 似乎有可靠的线程阻塞库。
【讨论】:
【参考方案7】:根据伊利亚的建议:
t1 = new Thread(() =>
while (keepRunning)
try
DoWork();
Thread.Sleep(all_night_long);
catch (ThreadInterruptedException)
);
t1.Start();
还有……
public void WakeUp()
t1.Interrupt();
public void StopRunningImmediately()
keepRunning = false;
WakeUp(); //immediately
这个解决方案是粗略的,因为可能有其他原因导致ThreadInterruptedException
被抛出。
【讨论】:
以上是关于有没有办法唤醒睡眠线程?的主要内容,如果未能解决你的问题,请参考以下文章