2012-04-06 67 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)你「信號」做工作的一個環路,信號返回'假' - 你需要重複每一個'新批'工作 - 這是一個簡單的。 (通常伴隨着一些「消息」被傳遞,當然以某種方式同步)。

希望這會增加一些信息,