2012-11-29 59 views
5

我有不同的任務從不同的文件中讀取並找到一個單詞。我已經把它們放入一個任務數組,我開始了WaitAny方法如下:如何在c中完成一個任務時停止所有任務#

foreach (string file in filesList) 
     { 
      files[i] = Task.Factory.StartNew(() => 
      { 
       mySearch.Invoke(file); 
      }); 
      i++; 
     } 
     System.Threading.Tasks.Task.WaitAny(files); 

我想盡快的任務之一完成停止所有其他任務(當它開創這個詞它完成)。目前,有了waitany,我可以知道一項任務何時完成,但我不知道如何知道哪一項已完成,以及如何停止其他任務。 達到此目的的最佳方法是什麼?

+0

完成的任務是否在某處留下了結果?這可能包括確定任務。完成的第一個任務還可以設置一個事件,由其主循環中的每個任務檢查,這會導致所有其他任務退出。在mySearch.Invoke中的 – HABO

+0

,它們應該是循環逐字地循環。 然後,您可以添加一個標誌,以便在標誌發出信號時循環中斷,當任何任務發現該字時,可以發信號通知標誌 – ComfortablyNumb

回答

2

您可以使用所有任務將共享的單個CancellationToken。方法mySearch.Invoke方法驗證值爲token.IsCancellationRequested取消任務。當某些任務完成時,通過CancellationTokenSource.Cancel()取消其他任務。

var tokenSource = new CancellationTokenSource(); 
var token = tokenSource.Token; 

foreach (string file in filesList) 
{ 
    // pass cancellation token to your task 
    files[i] = Task.Factory.StartNew(() => mySearch.Invoke(file, token), token); 
    i++; 
} 

Task.WaitAny(files); 
tokenSource.Cancel(); 

BTW當源是通過調用token.ThrowIfCancellationRequested()

2

創建任務時,你可以通過一個CancelationToken取消您可以強制令牌拋出OperationCanceledException。當其中一個任務完成時設置此令牌。 這將導致剩餘的任務使用此令牌到not execute。正在運行的任務可能會收到OperationCanceledException並停止。

1

我強烈建議您閱讀Stephen Toub的How do I cancel non-cancelable async operations?。基本上你需要做的是取消所有這些任務,但目前你沒有任何機制來取消它們。

理想的方法是在foreach之前創建CancellationTokenSource,將CancellationToken從該源傳遞給每個子任務,定期檢查該令牌並在您注意到它指示取消時停止工作。然後您可以取消WhenAny延續中的令牌源。

如果這不是一個選項,你需要決定是否重要的​​是要真正停止任務(這實際上是不能完成的),或者如果你只需要繼續處理你的代碼而不用等待它們完成(這很容易做到)。

相關問題