AggregateException.Flatten メソッド

定義

AggregateException インスタンスを 1 つの新しいインスタンスにフラット化します。Flattens an AggregateException instances into a single, new instance.

public:
 AggregateException ^ Flatten();
public AggregateException Flatten ();
member this.Flatten : unit -> AggregateException
Public Function Flatten () As AggregateException

戻り値

新しいフラット化された AggregateExceptionA new, flattened AggregateException.

次の例では、入れ子の AggregateException インスタンスが 1 つのループで平坦化され、処理されています。In the following example, nested AggregateException instances are flattened and handled in just one loop.

using System;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      var task1 = Task.Factory.StartNew(() => {
                     var child1 = Task.Factory.StartNew(() => {
                        var child2 = Task.Factory.StartNew(() => {
                            // This exception is nested inside three AggregateExceptions.
                            throw new CustomException("Attached child2 faulted.");
                        }, TaskCreationOptions.AttachedToParent);

                        // This exception is nested inside two AggregateExceptions.
                        throw new CustomException("Attached child1 faulted.");
                     }, TaskCreationOptions.AttachedToParent);
      });

      try {
         task1.Wait();
      }
      catch (AggregateException ae) {
         foreach (var e in ae.Flatten().InnerExceptions) {
            if (e is CustomException) {
               Console.WriteLine(e.Message);
            }
            else {
               throw;
            }
         }
      }
   }
}

public class CustomException : Exception
{
   public CustomException(String message) : base(message)
   {}
}
// The example displays the following output:
//    Attached child1 faulted.
//    Attached child2 faulted.
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim task1 = Task.Factory.StartNew(Sub()
                                           Dim child1 = Task.Factory.StartNew(Sub()
                                                                                 Dim child2 = Task.Factory.StartNew(Sub()
                                                                                                                       Throw New CustomException("Attached child2 faulted.")
                                                                                                                    End Sub,
                                                                                                                    TaskCreationOptions.AttachedToParent)
                                                                                                                    Throw New CustomException("Attached child1 faulted.")
                                                                              End Sub,
                                                                              TaskCreationOptions.AttachedToParent)
                                        End Sub)

      Try
         task1.Wait()
      Catch ae As AggregateException
         For Each ex In ae.Flatten().InnerExceptions
            If TypeOf ex Is CustomException Then
               Console.WriteLine(ex.Message)
            Else
               Throw
            End If
         Next
      End Try
   End Sub
End Module

Class CustomException : Inherits Exception
   Public Sub New(s As String)
      MyBase.New(s)
   End Sub
End Class
' The example displays the following output:
'       Attached child1 faulted.
'       Attached child2 faulted.

また、次の例のように、 AggregateException.Flatten メソッドを使用して、単一の AggregateException インスタンス内の複数のタスクによってスローされた複数の AggregateException インスタンスから内部例外を再スローすることもできます。You can also use the AggregateException.Flatten method to rethrow the inner exceptions from multiple AggregateException instances thrown by multiple tasks in a single AggregateException instance, as the following example shows.

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
public class Example
{
   public static void Main()
   {
        try {
            ExecuteTasks();
        }
        catch (AggregateException ae) {
            foreach (var e in ae.InnerExceptions) {
                Console.WriteLine("{0}:\n   {1}", e.GetType().Name, e.Message);
            }
        }
   }

   static void ExecuteTasks()
   {
        // Assume this is a user-entered String.
        String path = @"C:\";
        List<Task> tasks = new List<Task>();

        tasks.Add(Task.Run(() => {
                             // This should throw an UnauthorizedAccessException.
                              return Directory.GetFiles(path, "*.txt",
                                                        SearchOption.AllDirectories);
                           }));

        tasks.Add(Task.Run(() => {
                              if (path == @"C:\")
                                 throw new ArgumentException("The system root is not a valid path.");
                              return new String[] { ".txt", ".dll", ".exe", ".bin", ".dat" };
                           }));

        tasks.Add(Task.Run(() => {
                               throw new NotImplementedException("This operation has not been implemented.");
                           }));

        try {
            Task.WaitAll(tasks.ToArray());
        }
        catch (AggregateException ae) {
            throw ae.Flatten();
        }
    }
}
// The example displays the following output:
//       UnauthorizedAccessException:
//          Access to the path 'C:\Documents and Settings' is denied.
//       ArgumentException:
//          The system root is not a valid path.
//       NotImplementedException:
//          This operation has not been implemented.
Imports System.Collections.Generic
Imports System.IO
Imports System.Threading.Tasks

Module Example
    Public Sub Main()
       Try
          ExecuteTasks()
       Catch ae As AggregateException
          For Each e In ae.InnerExceptions
             Console.WriteLine("{0}:{2}   {1}", e.GetType().Name, e.Message,
                               vbCrLf)
          Next
       End Try
    End Sub

    Sub ExecuteTasks()
        ' Assume this is a user-entered String.
        Dim path = "C:\"
        Dim tasks As New List(Of Task)
        
        tasks.Add(Task.Run(Function()
                             ' This should throw an UnauthorizedAccessException.
                              Return Directory.GetFiles(path, "*.txt",
                                                        SearchOption.AllDirectories)
                           End Function))

        tasks.Add(Task.Run(Function()
                              If path = "C:\" Then
                                 Throw New ArgumentException("The system root is not a valid path.")
                              End If
                              Return { ".txt", ".dll", ".exe", ".bin", ".dat" }
                           End Function))

        tasks.Add(Task.Run(Sub()
                              Throw New NotImplementedException("This operation has not been implemented.")
                           End Sub))

        Try
            Task.WaitAll(tasks.ToArray)
        Catch ae As AggregateException
            Throw ae.Flatten()
        End Try
    End Sub
End Module
' The example displays the following output:
'       UnauthorizedAccessException:
'          Access to the path 'C:\Documents and Settings' is denied.
'       ArgumentException:
'          The system root is not a valid path.
'       NotImplementedException:
'          This operation has not been implemented.

注釈

タスクに、例外をスローする子タスクがアタッチされている場合、その例外は親タスクに反映される前に AggregateException 例外にラップされます。これにより、その例外は、呼び出し元のスレッドに反映される前に、独自の AggregateException 例外でラップされます。If a task has an attached child task that throws an exception, that exception is wrapped in an AggregateException exception before it is propagated to the parent task, which wraps that exception in its own AggregateException exception before it propagates it back to the calling thread. このような場合、Task.WaitWaitTask.WaitAny、または Task.WaitAll メソッドによってキャッチされる AggregateException 例外の InnerExceptions プロパティには、エラーの原因となった元の例外ではなく、1つ以上の AggregateException インスタンスが含まれます。In such cases, the InnerExceptions property of the AggregateException exception that is caught by the Task.Wait, Wait, Task.WaitAny or Task.WaitAll method contains one or more AggregateException instances, not the original exceptions that caused the fault. 入れ子になった AggregateException 例外を反復処理しなくても済むように、Flatten メソッドを使用して、返された AggregateException オブジェクトの InnerExceptions プロパティに元の例外が含まれるように、入れ子になったすべての AggregateException 例外を削除できます。To avoid having to iterate over nested AggregateException exceptions, you can use the Flatten method to remove all the nested AggregateException exceptions, so that the InnerExceptions property of the returned AggregateException object contains the original exceptions.

このメソッドは、現在の AggregateException インスタンスの内部例外である AggregateException 例外のすべてのインスタンスを再帰的に平坦化します。This method recursively flattens all instances of AggregateException exceptions that are inner exceptions of the current AggregateException instance . 新しい AggregateException で返される内部例外は、現在の AggregateException インスタンスをルートとする例外ツリーからのすべての内部例外の和集合です。The inner exceptions returned in the new AggregateException are the union of all the inner exceptions from exception tree rooted at the current AggregateException instance.

適用対象

こちらもご覧ください