2017-05-25 88 views
0

我正在使用此代碼來執行任務恢復和暫停。我需要暫停,因爲doSomething();方法不會每次都工作,例如當數據來自web api時。所以CPU不會疲勞。我在很多項目中都使用這個技術。但我不確定這是可靠的還是最好的方法。我可以問你的想法嗎?對於任務暫停和恢復我可以使用ManualResetEventSlim嗎?

static ManualResetEventSlim mre = new ManualResetEventSlim(false); 
    static void Main(string[] args) 
    { 

     mre.Set(); 
     Task.Factory.StartNew(() => 
     { 
      while (true) 
      { 
       mre.Wait(); 
       doSomething(); 
      } 

     }); 

     mre.Reset(); 
     Console.WriteLine("Task Paused"); 
     Console.WriteLine("Task Will Resume After 1 Second"); 
     Thread.Sleep(1000);//To simulate, waiting data from Web Api etc. for doSomething(); 
     mre.Set(); 

     Console.Read(); 
    } 
+0

這是一個代碼審查問題,你應該問一下https://codereview.stackexchange.com/ –

+1

你在'mre.mait()'和'mre.Reset()'之間有競爭條件。設置()'。有可能mre.Wait()的執行速度比重置信號的速度快,因此你的'doSomething()'方法在第一個Thread.Sleep()之前觸發。如果在mre.Reset()之前添加Thread.Sleep(10),則可以輕鬆地進行仿真。 – Szer

+3

如果你認爲你需要「暫停」一項任務,那麼你做錯了什麼。在這種情況下,您將任務視爲線程。不是。你*不需要那個無限循環。還有其他方法可以執行不需要浪費線程的任務 –

回答

1

您可以使用SemaphoreSlim

SemaphoreSlim _semaphore; 
static void Main(string[] args) 
    { 
     _semaphore = new SemaphoreSlim(0); 

     Task.Factory.StartNew(() => 
     { 
      while (true) 
      { 
       _semaphore.Wait(); 
       doSomething(); 
      } 

     }); 

     _semaphore.Release(); 
     Console.WriteLine("Task Paused"); 
     Console.WriteLine("Task Will Resume After 1 Second"); 
     Thread.Sleep(1000);//To simulate, waiting data from Web Api etc. for doSomething();  
     _semaphore.Release(); 
     Console.Read(); 
    } 

信號燈會一直過渡到 內核;相比之下,與ManualResetEventSlim,SemaphoreSlim已被設計爲留在用戶模式作爲 儘量,典型地導致對過程內螺紋通信更好的性能和可擴展性。
SemaphoreSlim還 提供CURRENTCOUNT屬性它可以訪問該計數值時,通常僅用於調試 目的。

注意事項:

與ManualResetEventSlim,訪問的 底層內核對象SemaphoreSlim的AvailableWaitHandle屬性力量的初始化。這增加了後續等待和釋放調用的開銷,現在需要 維持WaitHandle的狀態。

請注意,此屬性的名稱AvailableWaitHandle與 ManualResetEventSlim上的WaitHandle屬性的名稱不同。這是由於返回的WaitHandle中的功能差異。等待一個ManualResetEvent的 或ManualResetEventSlim不會改變事件的信號狀態。然而,等待信號量的 可能會改變信號量,因爲它可以減少信號量的內部計數。這樣, 的AvailableWaitHandle屬性返回WaitHandle的,僅僅表示高可能性有計數 可用於在SemaphoreSlim消耗;要實際獲得對關聯的共享資源的訪問權,然而,必須直接在SemaphoreSlim上等待。

這一切意味着可能與信號量一定的同步操作是不可能與 SemaphoreSlim。例如,與信號量,能夠使用WaitHandle.WaitAll的以原子方式獲取從多個信號量 資源;該功能在SemaphoreSlim中不存在。

+0

_semaphore.Release()將被調用,只要真是假=>我想這將永遠不會發生 –

+1

而問題是關於暫停任務執行,而不是暫停主執行 –

+0

@SirRufo - 你是對的。我改變了我的答案。 –