2

私は並列化する予定のコードをいくつか持っています。例外スタックトレースと集約foreach

それはこの

foreach(var item in collection) 
{ 
     if(error) 
     { 
     throw new Exception(); 
     } 
} 

例外のようないくつかのことを見て、それがスタックトレースには、この

Parallel.ForEach(collection, item=> 
{ 
     if(error) 
      { 
      throw new Exception(); 
      } 
}); 
  1. のようになります。並列化した後、ログファイルに保存

    ですこの例外はどのように他のアイテムの並列実行を停止するのでしょうか?ループスレッドでエラーが発生すると、他のすべての実行を停止する方法はありますか?

  2. 例外スタックトレースにはどのような影響がありますか?

答えて

2
  1. 例外が発生した場合、まだスケジュールされていない項目の実行がキャンセルされます。ただし、既にスケジュールされているため、実行中です(これは並行して行われるため、最初はParallelを使用しているため、キャンセルされることはありません)。それらは最後まで実行され、例外もスローされます。

  2. 上記から、並列ループで複数の例外がスローされることがあります。そのため、彼らは常にAggregateExceptionにラップされています(ただ1つの例外がある場合でも)。だから、その例外をキャッチし、それが一緒にスタックトレースで、スローされるすべての例外が含まれているInnerExceptionsプロパティだを列挙することができます

    try { 
        Parallel.ForEach(collection, item=> 
        { 
         if(error) 
         { 
          throw new Exception(); 
         } 
        }); 
    } 
    catch (AggregateException ex) { 
        foreach (var exception in ex.InnerExceptions) { 
         // do something  
        } 
    } 
    
0

次のコードは、最初の部分で述べた動作を確認するために使用することができますEvkの答え:

static void TryCatchFunction() 
    { 
     ConcurrentBag<string> bag = null; 
     int numItemsInBag = 0; 
     try 
     { 
      ErrorFunction(out bag); 
      numItemsInBag = bag.Count; 
     } 
     catch (Exception) 
     { 
      numItemsInBag = bag.Count; 
     } 
    } 

    static void ErrorFunction(out ConcurrentBag<string> bag) 
    { 
     string[] strings = new string[] { "1", "2", "3", "4", "5", "6" }; 
     ConcurrentBag<string> inFunctionBag = new ConcurrentBag<string>(); 
     bag = inFunctionBag; 

     Parallel.ForEach(strings, (str, state) => 
     { 
      if (str == "2" || str == "4") 
      { 
       inFunctionBag.Add(str); 
       throw new Exception(); 
      } 
     }); 
    } 

デュアルコアマシンでのメソッド呼び出しによって項目数が異なります。これは、例外が他のスレッドの実行をキャンセルすることがあり、それ以外のときに両方が完了するまで実行されることがあるためです。

関連する問題