AggregateException.InnerExceptions
InnerExceptionsプロパティに集約された例外がセットされている。
今回は複数のタスクをWait()しているが、タスクが、アタッチされた子タスクの親である場合にも例外が集約される。
public class AggregateExceptionExample
{
public static void Run()
{
var tasks = new List<Task>();
tasks.Add(Task.Factory.StartNew(() => { throw new Exception("Error1"); }));
tasks.Add(Task.Factory.StartNew(() => { throw new Exception("Error2"); }));
tasks.Add(Task.Factory.StartNew(() => { throw new Exception("Error3"); }));
try
{
Task.WaitAll(tasks.ToArray());
}
catch (AggregateException exc)
{
//Error1 ~ Error3 が出力される
foreach (var e in exc.InnerExceptions)
{
Console.WriteLine(e.Message);
}
}
}
}
AggregateException.Handle()
Handleに例外に対する対応実施の有無を返すラムダ式を指定することで、フィルタリング的な挙動を行うことができる。
public class AggregateExceptionExample2Runnter
{
public static void Run()
{
try
{
AggregateExceptionExample2.Run();
}
catch (AggregateException exc)
{
//Error1 と Error2 が出力される
foreach (var e in exc.InnerExceptions)
{
Console.WriteLine(e.Message);
}
}
}
}
public class MyException : Exception
{
public MyException(string msg) : base(msg) { }
}
public class AggregateExceptionExample2
{
public static void Run()
{
var tasks = new List<Task>();
tasks.Add(Task.Factory.StartNew(() => { throw new Exception("Error1"); }));
tasks.Add(Task.Factory.StartNew(() => { throw new MyException("MyError"); }));
tasks.Add(Task.Factory.StartNew(() => { throw new Exception("Error2"); }));
try
{
Task.WaitAll(tasks.ToArray());
}
catch (AggregateException exc)
{
exc.Handle((e) =>
{
//true:例外処理した、false:例外処理していない
return e.GetType() == typeof(MyException);
});
}
}
}
AggregateException.Flatten()
Flatten()でAggregateExceptionのネストを平坦化することができる。
public class AggregateExceptionExample3
{
public static void Run()
{
var tasks = new List<Task>();
tasks.Add(Task.Factory.StartNew(() => { throw new Exception("Error1"); }));
tasks.Add(Task.Factory.StartNew(() => { throw new Exception("Error2"); }));
tasks.Add(Task.Factory.StartNew(() => {
var tasks2 = new List<Task>();
tasks2.Add(Task.Factory.StartNew(() => { throw new Exception("Error3-1"); }));
tasks2.Add(Task.Factory.StartNew(() => { throw new Exception("Error3-2"); }));
tasks2.Add(Task.Factory.StartNew(() => { throw new Exception("Error3-3"); }));
Task.WaitAll(tasks2.ToArray());
}));
try
{
Task.WaitAll(tasks.ToArray());
}
catch (AggregateException exc)
{
foreach (var e in exc.Flatten().InnerExceptions)
{
Console.WriteLine(e.Message);
}
}
}
}