LoginSignup
12
8

More than 5 years have passed since last update.

AggregateExceptionで集約された例外に対する処理いろいろ

Last updated at Posted at 2014-11-29

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);
            }
        }
    }
}
12
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
8