2012-04-06 75 views
1

我有一个工作线程,可能在短时间内处于活动状态,在其余时间处于空闲状态。我正在考虑让线程进入睡眠状态,然后在需要时唤醒线程。临时挂起工作线程的正确方法

对此I的其他建议应该注意?

谢谢!

  • 这是C#/。NET4
+0

您使用哪种语言? – 2012-04-06 18:25:42

+0

感谢您的支持!我更新了这篇文章。 – AlexVPerl 2012-04-06 18:27:21

+0

这是什么决定线程何时变为活动状态? – 2012-04-06 18:29:28

回答

2

只需使用事件来暂停工作线程:重置 - 暂停,设置 - 取消暂停(工作)状态。

这里是草案版本的代码,演示了这种方法。

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(); 
    } 
} 
4

你可能不应该使用持久性工作者thread-使用线程池。这正是它的目的。

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

+0

您知道QueueUserWorkItem是在1个新线程还是多个线程上执行吗?意思是说,如果你两次调用两个独立的工作项目,是否有保证,两者都将按顺序运行或通过调用我们完全放弃控制并且可以产生多个新线程? – AlexVPerl 2012-04-06 20:35:43

+0

后者。除非手动同步他们的工作,否则您将拥有多个线程。 – 2012-04-06 22:51:27

1

与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. 
} 

注:
出口是ManualResetEvent与 '假' 的初始状态 - '设置' 事件退出。
_newWork或者是在你需要暂停/从外部继续这就是你想要什么,我认为这种情况下Manual -
......或者也可能是new AutoResetEvent(false)你“信号”做工作的一个环路,信号返回'假' - 你需要重复每一个'新批'工作 - 这是一个简单的。 (通常伴随着一些“消息”被传递,当然以某种方式同步)。

希望这会增加一些信息,