AggregateException.Flatten メソッド
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
AggregateException インスタンスを 1 つの新しいインスタンスにフラット化します。
public:
AggregateException ^ Flatten();
public AggregateException Flatten ();
member this.Flatten : unit -> AggregateException
Public Function Flatten () As AggregateException
戻り値
新しいフラット化された AggregateException。
例
次の例では、入れ子の AggregateException インスタンスが 1 つのループで平坦化され、処理されています。
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.
open System
open System.Threading.Tasks
type CustomException(message) =
inherit Exception(message)
let task1 =
Task.Factory.StartNew (fun () ->
let child1 =
Task.Factory.StartNew(
(fun () ->
let child2 =
Task.Factory.StartNew(
(fun () -> raise (CustomException "Attached child2 faulted,")),
TaskCreationOptions.AttachedToParent
)
raise (CustomException "Attached child1 faulted.")),
TaskCreationOptions.AttachedToParent
)
()
)
try
task1.Wait()
with
| :? AggregateException as ae ->
for e in ae.Flatten().InnerExceptions do
if e :? CustomException then
printfn "%s" e.Message
else
reraise()
// 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 インスタンスから内部例外を再スローすることもできます。
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
public class Example2
{
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.
open System
open System.IO
open System.Threading.Tasks
let executeTasks () =
// Assume this is a user-entered String.
let path = @"C:\"
let tasks =
[| Task.Run (fun () ->
// This should throw an UnauthorizedAccessException.
Directory.GetFiles(path, "*.txt", SearchOption.AllDirectories))
:> Task
Task.Run (fun () ->
if path = @"C:\" then
raise (ArgumentException "The system root is not a valid path.")
[| ".txt"; ".dll"; ".exe"; ".bin"; ".dat" |])
:> Task
Task.Run(fun () -> raise (NotImplementedException "This operation has not been implemented")) |]
try
Task.WaitAll(tasks)
with
| :? AggregateException as ae -> raise (ae.Flatten())
try
executeTasks ()
with
| :? AggregateException as ae ->
for e in ae.InnerExceptions do
printfn $"{e.GetType().Name}:\n {e.Message}"
// 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 の例外でラップされます。 このような場合、InnerExceptionsまたは Task.WaitAll メソッドによってキャッチされる例外の AggregateException プロパティには、エラーのTask.WaitWaitTask.WaitAny原因となった元の例外ではなく、1 つ以上AggregateExceptionのインスタンスが含まれます。 入れ子になったAggregateException例外を反復処理する必要を回避するには、 メソッドをFlatten使用して入れ子になったAggregateExceptionすべての例外を削除し、返されるオブジェクトの プロパティにAggregateException元の例外が含まれるようにInnerExceptionsすることができます。
このメソッドは、現在AggregateExceptionのインスタンスのAggregateException内部例外である例外のすべてのインスタンスを再帰的にフラット化します。 新しい AggregateException で返される内部例外は、現在 AggregateException のインスタンスにルート化された例外ツリーからのすべての内部例外の和集合です。
適用対象
こちらもご覧ください
.NET