2017-10-11 122 views
0

我有以下測試代碼來模擬信號量和限制任務執行的使用。如果其中一個正在運行的任務拋出像下面這樣的異常,是否有辦法不繼續創建新任務?我不需要現有的任務來停止運行,我只是希望遇到異常後不會有新的任務啓動。如果在當前正在運行的任務中發生異常,停止執行半任務任務

當前任務將在下面的這種情況下開始。我想讓它在因拋出異常而運行幾個任務之後停止。

  var testStrings = new List<string>(); 
      for (var i = 0; i < 5000; i++) 
      { 
       testStrings.Add($"string-{i}"); 
      } 

      using (var semaphore = new SemaphoreSlim(10)) 
      { 
       var tasks = testStrings.Select(async testString => 
       { 
        await semaphore.WaitAsync(); 
        try 
        { 
         Console.WriteLine($"{testString}-Start"); 
         await Task.Delay(2000); 
         throw new Exception("test"); 
        } 
        finally 
        { 
         semaphore.Release(); 
        } 
       }); 

       await Task.WhenAll(tasks); 
      } 
+0

天真的方法是設置錯誤標誌並從任何任務返回(即使在執行過程中,如果你想)如果標誌設置。這有開銷仍然不得不開始所有的任務。 – Sinatr

+1

[如何取消並在Task.WhenAll上引發異常(如果發生任何異常?)可能的重複?](https://stackoverflow.com/questions/41899842/how-to-cancel-and-raise-an-exception-如果任何異常被提出) – Sinatr

+0

我想如果我添加一個catch塊給我的嘗試,並說如果(!cancellationTokenSource.IsCancellationRequested) cancellationTokenSource.Cancel();然後將每個包裝在可能有效的if(!cancellationToken.IsCancellationRequested)中 – mameesh

回答

1

根據Sinatr的評論,我認爲這可能適用於我通過添加取消令牌進行監控。

 var testStrings = new List<string>(); 
     for (var i = 0; i < 5000; i++) 
     { 
      testStrings.Add($"string-{i}"); 
     } 

     var cancellationTokenSource = new CancellationTokenSource(); 
     var cancellationToken = cancellationTokenSource.Token; 

     using (var semaphore = new SemaphoreSlim(10)) 
     { 
      var tasks = testStrings.Select(async testString => 
      { 
        await semaphore.WaitAsync(); 
        try 
        { 
         if (!cancellationToken.IsCancellationRequested) 
         { 
          Console.WriteLine($"{testString}-Start"); 
          await Task.Delay(2000); 
          throw new Exception("test"); 
         } 
        } 
        catch (Exception ex) 
        { 
         if (!cancellationTokenSource.IsCancellationRequested) 
          cancellationTokenSource.Cancel(); 
         throw; 
        } 
        finally 
        { 
         semaphore.Release(); 
        } 
      }); 

      await Task.WhenAll(tasks); 
     } 
相關問題