2011-02-28 74 views
3

我想知道一個正確的方式來啓動和停止強制和非強制的線程作業。這是停止線程的正確方法嗎?啓動和停止(強制)線程作業

public class ProcessDataJob : IJob 
    { 
     private ConcurrentQueue<byte[]> _dataQueue = new ConcurrentQueue<byte[]>(); 
     private volatile bool _stop = false; 
     private volatile bool _forceStop = false; 
     private Thread _thread; 
     private int _timeOut = 1000; 

     public void Start() 
     { 
      _stop = false; 
      _forceStop = false; 

      _thread = new Thread(ProcessData); 
      _thread.Start(); 
     } 

     private void ProcessData() 
     { 
      while (!_stop || _dataQueue.Count > 0) 
      { 
       if(_forceStop) return; 

       byte[] data; 
       if(_dataQueue.TryDequeue(data)) 
       { 
        //Process data 
        //.....// 
       } 
      } 
     } 

     public void Stop(bool force) 
     { 
      _stop = true; 
      _forceStop = force; 
      _thread.Join(_timeOut); 
     } 

     public void Enqueue(byte[] data) 
     { 
      _dataQueue.Enqueue(data); 
     } 
    } 

回答

7

沒有正確方式強行殺死一個線程。

有幾種方法可以做到,但它們都不是正確

只有當您需要終止程序或卸載包含線程的appdomain,並且不關心任何數據結構懸掛在損壞/錯誤/鎖定狀態時,強制終止線程纔是您應該執行的操作,因爲他們也會在短時間內消失。

在互聯網上有很多關於壞/邪惡Thread.Abort的建議,所以不要這樣做。

而是編寫適當的協作式線程。線程應該自己檢查一個標誌(事件,易失性布爾字段等),然後當很好地要求這樣做時,它會自動退出。

這就是正確的方式。

+0

+1我完全同意你的觀點,並且OP已經是doint了:-)那麼,什麼時候使用'Thread.Abort'甚至可以想象?也許從未? –

+0

如果你需要卸載appdomain(想殺死一個正在運行的擴展/插件)或者退出程序,並且你知道/不在乎有沒有線程運行時沒有配置IsBackground屬性。基本上,你想快速擺脫appdomain /應用程序,不希望等待所有線程自行退出。儘管如此,說實話,即使在這種情況下,我可能仍然不會使用Thread.Abort。把它看作是一個操作系統的功能,對於我們這些凡人來說,這個功能基本上太低了。讓Eric Lippert和其他人來照顧它吧。 –

+0

是的,爲此我會使用'AppDomain.Unload'(在封面下使用'Thread.Abort')。 –

0

您可以使用.NET ThreadPool類,這樣您就不必自己處理堆棧。

+0

不是一個好的答案。這裏沒有Stack(待管理)。對於TP來說,這看起來太長了。 –

+0

@亨克 - 你*可以*通過對QueueUserWorkItem的調用來代替所有這些。這在Gergroen環境中可以嗎?我們不能說,但也許值得。 –

+0

推送到TP不會使循環和停止( - 問題)消失。 –

1

這是我過去做過的,只有一個區別。我的線程意外掛在過去,這意味着你的循環不會回來的答案。爲了解決這個問題,我讓所有線程都像你一樣使用類,註冊一個負責參與關鍵事情的「經理」類,如強迫停止。線程類具有對管理器的引用,當強制停止完成時,它將調用管理器上的一個方法,該方法實際上是一個計時器。如果在計時器關閉時,線程類沒有將狀態標誌設置爲「已停止」,則管理器將對其進行中止。

對我來說,關鍵的不僅是呼叫'停止',而且確認'停止'已經發生,並且理解它將是非確定性的時間量,但是'經過合理的時間量'我應該放棄並繼續前進。