我有一个工作线程,它可能在短时间内处于活动状态,而在其余时间处于空闲状态。我正在考虑让线程进入睡眠状态,然后在需要时唤醒它。
我应该注意的任何其他建议?
谢谢!
- 这是在 C#/.NET4 中
我有一个工作线程,它可能在短时间内处于活动状态,而在其余时间处于空闲状态。我正在考虑让线程进入睡眠状态,然后在需要时唤醒它。
我应该注意的任何其他建议?
谢谢!
您可能不应该使用持久工作线程 - 使用线程池。这正是它的目的。
ThreadPool.QueueUserWorkItem(() => {
// My temporary work here
});
如果你坚持要有一个持久的工作线程,让它运行这个:
// This is our latch- we can use this to "let the thread out of the gate"
AutoResetEvent threadLatch = new AutoResetEvent(false);
// The thread runs this
public void DoBackgroundWork() {
// Making sure that the thread is a background thread
// ensures that the endless loop below doesn't prevent
// the program from exiting
Thread.IsBackground = true;
while (true) {
// The worker thread will get here and then block
// until someone Set()s the latch:
threadLatch.WaitOne();
// Do your work here
}
}
// To signal the thread to start:
threadLatch.Set();
另请注意,如果此后台线程要与用户界面交互,则需要相应地调用或 BeginInvoke。见http://weblogs.asp.net/justin_rogers/pages/126345.aspx
只需使用一个事件来暂停工作线程:重置 - 暂停,设置 - 未暂停(工作)状态。
这是演示该方法的代码草案版本。
class Worker
{
private Thread _thread;
// Un-paused by default.
private ManualResetEvent _notToBePaused = new ManualResetEvent(true);
public Worker()
{
_thread = new Thread(Run)
{
IsBackground = true
};
}
/// <summary>
/// Thread function.
/// </summary>
private void Run()
{
while (true)
{
// Would block if paused!
_notToBePaused.WaitOne();
// Process some stuff here.
}
}
public void Start()
{
_thread.Start();
}
public void Pause()
{
_notToBePaused.Reset();
}
public void UnPause()
{
_notToBePaused.Set();
}
}
使用 WaitHandle 发出信号是正确的方法,但只是补充其他人已经说过的话
我通常会使用 2 个信号一起工作,否则您将不知道在需要时是“继续”还是“退出” - 或者不得不采取一种不太优雅的方式来做到这一点(停止线程 - 当然有还有其他做这样的事情的方法,只是一个“模式”)。所以通常它与“退出”信号和“新工作可用”信号一起工作 - 协同工作。例如
WaitHandle[] eventArray = new WaitHandle[2] { _exitEvent, _newWorkEvent };
while ((waitid = WaitHandle.WaitAny(eventArray, timeout, false)) > 1)
{
// do your work, and optionally handle timeout etc.
}
注意:
exitManualResetEvent
初始状态为“假”-“设置”事件退出。
_newWork
是Manual
在这种情况下,您需要从外部暂停/继续,这就是您想要的-我认为-
...或者也可能是new AutoResetEvent(false)
您“发出信号”以进行一个工作循环,信号立即返回“假”-并且您需要为每个“新批次”工作重复这一点 - 这有点简化。(通常这与传递一些“消息”密切相关,当然以某种方式同步)。
希望这会增加更多信息,