2010-02-12 81 views
2

我做了一些研究,並環顧四周,似乎要做到這一點的方法是使用AutoResetEvent。我很快把它放在一起,它似乎工作,似乎是線程安全的。我可以有一些反饋嗎?編輯: 嗨,再次。我已經使用了反饋,我對我的實現感到滿意。只是我想補充的一件小事,當我暫停時,我想等待確保線程已經暫停並且不再工作。那可能嗎?也許我應該只更換暫停和恢復,只有開始和停止,然後停止做一個thred.join()。註釋?.Net Thread.Suspend已過時。尋找替代品

+1

我不知道在ContinueProcessing setter中是否會遇到訂購問題? – ziya 2010-02-12 12:36:45

+0

你設置_continueProcessing兩次 - 鎖定和解鎖 – tanascius 2010-02-12 12:37:38

+0

也許你應該把所有的鎖(在ContinueProcessing setter中)或考慮一種不使用標誌的方式? http://dotnet.org.za/markn/archive/2008/10/21/net-memory-model-bytecode-reordering.aspx – ziya 2010-02-12 12:44:52

回答

1

一旦調用exit,ManualResetEvent就會被拋棄,並且在調用時可能會在實例方法上拋出異常。 - >在某些情況下,這可能不是理想的

class Program { 
     static void Main(string[] args) { 

      //NOTE: if worker goes out of scope it will be collected -> ex: promote to field in real use 
      Worker worker = new Worker(); 
      System.Threading.Thread workerThread = new System.Threading.Thread(new System.Threading.ThreadStart(worker.DoWork)); 
      workerThread.IsBackground = true; 
      workerThread.Start(); 

      // test 
      worker.Resume(); 
      System.Threading.Thread.Sleep(2000); 

      worker.Pause(); 
      System.Threading.Thread.Sleep(2000); 

      worker.Resume(); 
      System.Threading.Thread.Sleep(2000); 

      worker.Exit(); 
      System.Threading.Thread.Sleep(5000);   
     } 
    } 

    public class Worker { 

     private readonly System.Threading.ManualResetEvent _Gate; 
     private bool _IsActive; 

     public Worker() { 

      _Gate = new System.Threading.ManualResetEvent(false); 
      _IsActive = true; 
     } 

     public void DoWork() { 

      while (IsActive) { 
       _Gate.WaitOne(); 
       // do work 

       // can yield the thread 
       System.Threading.Thread.Sleep(1); 
      } 

      // dispose 
      _Gate.Close(); 
     } 

     private bool IsActive { 
      get { 
       lock (_Gate) { 
        return _IsActive; 
       } 
      } 
     } 

     public void Pause() { 
      _Gate.Reset(); 
     } 

     public void Resume() { 
      _Gate.Set(); 
     } 

     public void Exit() { 
      lock (_Gate) { 
       _IsActive = false; 
      } 
     } 
    } 
0

看起來過於複雜

public void StopProcessing() 
    { 
     workerThread.Interrupt(); 
     workerThread.Join(); 
    } 

可以,如果你只是讓線程退出的方法

0

如果改爲使用ManualResetEvent的,你可以刪除_continueProcessing變量被刪除。在設置中,只需調用事件的Set或Reset。在getter中,你可以返回aResetEvent.WaitOne(0)。然後,您可以在DoSomeProcessing結束時刪除一段代碼,以便在處理應該持續時設置該事件。另外,因爲ManualResetEvent本身是線程安全的,您可以完全刪除您的鎖定。

關於退出DoSomeProcessing方法。也許最好的辦法是使用你設置的標誌來告訴循環退出,在循環開始時用鎖來測試標誌(是的,你現在必須把一些鎖定回去),當你想要放棄,您設置標誌,然後設置事件。

或者,您可以使用另一個事件來指示循環應該退出並更改您的等待以使用WaitHandle.WaitAny()。