2016-07-08 92 views
0

如果在控制檯應用程序內運行而不是拋出AggregateException並被外部try/catch捕獲,爲什麼會發生以下崩潰?爲什麼異步Parallel.ForEach中的異常會使應用程序崩潰?

爲簡潔起見,我簡化了await的用例,但在相關代碼中,我確實試圖執行一個等待重要的Task

var list = new List<string>() {"Error"}; 

     try 
     { 
      Parallel.ForEach(list, new ParallelOptions() 
      { 
       MaxDegreeOfParallelism = 8 
      }, async listEntry => 
      { 
       await Task.Delay(5000); 
       throw new Exception("Exception"); 
      }); 
     } 
     catch (Exception ex) 
     { 
      //never hits, the application crashes 
     } 

     Console.ReadLine(); 

我注意到以下不會導致應用程序失敗,並異常確實抓住了,但我不明白到底發生了什麼對,什麼是關於兩個背景完全不同的:

var list = new List<string>() {"Error"}; 

     try 
     { 
      Parallel.ForEach(list, new ParallelOptions() 
      { 
       MaxDegreeOfParallelism = 8 
      }, listEntry => 
      { 

       throw new Exception("Exception"); 
      }); 
     } 
     catch (Exception ex) 
     { 
      //exception is caught, application continues 
     } 

     Console.ReadLine(); 
+0

我沒有看到任何代碼在任務的異步部分捕獲異常 - 這確實會導致無用的異常和終止進程...附註:我不太清楚爲什麼你需要'Parallel.ForEach'當你不關心它們如何結束時,開始多個任務...如果你真的需要類似於這篇文章中的代碼,你可以搜索「C#發射並忘記異步」。 –

+0

@AlexeiLevenkov,我想我的問題是......爲什麼我需要在循環中捕捉它,因爲它是異步的?當它是同步的,它不需要。另外,這不是一場火災,而是忘記了,在我的實際代碼中,我正在調用一個可以等待的函數,我只是簡單地簡化了用例,並用一個空的任務簡化了用例。 –

+3

不要將'Parallel.ForEach'與'async/await'混合在一起http://stackoverflow.com/questions/11564506/nesting-await-in-parallell-foreach – MickyD

回答

4

正如評論中提到的那樣,you shouldn't mix async and Parallel.ForEach,它們不能一起工作。

您看到的是什麼的那後果之一:拉姆達被編譯爲一個async void方法和當async void方法拋出,異常被重新拋出其SynchronizationContext,這通常會導致應用程序崩潰。

+0

謝謝你的解釋,這非常有幫助。 –

相關問題