Try...Catch...Finally ステートメント (Visual Basic)Try...Catch...Finally Statement (Visual Basic)

コードを実行したまま、特定のコードブロックで発生する可能性のあるエラーの一部またはすべてを処理する方法を提供します。Provides a way to handle some or all possible errors that may occur in a given block of code, while still running code.

構文Syntax

Try
    [ tryStatements ]
    [ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
    [ catchStatements ]
    [ Exit Try ] ]
[ Catch ... ]
[ Finally
    [ finallyStatements ] ]
End Try

のコンポーネントParts

用語Term DefinitionDefinition
tryStatements 省略可。Optional. エラーが発生する可能性のあるステートメント。Statement(s) where an error can occur. 複合ステートメントにすることもできます。Can be a compound statement.
Catch 省略可。Optional. 複数の Catch ブロックが許可されています。Multiple Catch blocks permitted. Try ブロックの処理中に例外が発生した場合、各 Catch ステートメントは、スローされた例外を表す exception を使用して、例外を処理するかどうかを判断するためにテキスト順に検証されます。If an exception occurs when processing the Try block, each Catch statement is examined in textual order to determine whether it handles the exception, with exception representing the exception that has been thrown.
exception 省略可。Optional. 任意の変数名を指定します。Any variable name. exception の初期値は、スローされたエラーの値です。The initial value of exception is the value of the thrown error. キャッチされたエラーを指定するために Catch と共に使用します。Used with Catch to specify the error caught. 省略した場合、Catch ステートメントは例外をキャッチします。If omitted, the Catch statement catches any exception.
type 省略可。Optional. クラスフィルターの種類を指定します。Specifies the type of class filter. exception の値が、type または派生型のによって指定された型である場合、識別子は例外オブジェクトにバインドされます。If the value of exception is of the type specified by type or of a derived type, the identifier becomes bound to the exception object.
When 省略可。Optional. When 句を含む Catch ステートメントは、expressionTrueに評価された場合にのみ例外をキャッチします。A Catch statement with a When clause catches exceptions only when expression evaluates to True. When 句は、例外の型をチェックした後にのみ適用され、expression は例外を表す識別子を参照する場合があります。A When clause is applied only after checking the type of the exception, and expression may refer to the identifier representing the exception.
expression 省略可。Optional. Booleanに暗黙的に変換可能である必要があります。Must be implicitly convertible to Boolean. 汎用フィルターを記述する任意の式。Any expression that describes a generic filter. 通常、エラー番号でフィルター処理するために使用されます。Typically used to filter by error number. When キーワードと共に使用して、エラーがキャッチされる状況を指定します。Used with When keyword to specify circumstances under which the error is caught.
catchStatements 省略可。Optional. 関連付けられている Try ブロックで発生したエラーを処理するステートメント。Statement(s) to handle errors that occur in the associated Try block. 複合ステートメントにすることもできます。Can be a compound statement.
Exit Try 省略可。Optional. Try...Catch...Finally 構造体を分割するキーワード。Keyword that breaks out of the Try...Catch...Finally structure. End Try ステートメントの直後のコードで実行が再開されます。Execution resumes with the code immediately following the End Try statement. Finally ステートメントは引き続き実行されます。The Finally statement will still be executed. Finally ブロックでは許可されていません。Not allowed in Finally blocks.
Finally 省略可。Optional. Finally ブロックは、実行が Try...Catch ステートメントの任意の部分を離れると常に実行されます。A Finally block is always executed when execution leaves any part of the Try...Catch statement.
finallyStatements 省略可。Optional. 他のすべてのエラー処理が発生した後に実行されるステートメントです。Statement(s) that are executed after all other error processing has occurred.
End Try Try...Catch...Finally 構造体を終了します。Terminates the Try...Catch...Finally structure.

RemarksRemarks

特定の例外がコードの特定のセクションで発生することが予想される場合は、コードを Try ブロックに配置し、Catch ブロックを使用してコントロールを保持し、発生した場合は例外を処理します。If you expect that a particular exception might occur during a particular section of code, put the code in a Try block and use a Catch block to retain control and handle the exception if it occurs.

Try…Catch ステートメントは、Try ブロックと、さまざまな例外のハンドラーを指定する1つ以上の Catch 句で構成されます。A Try…Catch statement consists of a Try block followed by one or more Catch clauses, which specify handlers for various exceptions. Try ブロックで例外がスローされると、Visual Basic は例外を処理する Catch ステートメントを検索します。When an exception is thrown in a Try block, Visual Basic looks for the Catch statement that handles the exception. 一致する Catch ステートメントが見つからない場合、Visual Basic は、現在のメソッドを呼び出したメソッド、および呼び出し履歴を調べます。If a matching Catch statement is not found, Visual Basic examines the method that called the current method, and so on up the call stack. Catch ブロックが見つからない場合、Visual Basic はハンドルされない例外メッセージをユーザーに表示し、プログラムの実行を停止します。If no Catch block is found, Visual Basic displays an unhandled exception message to the user and stops execution of the program.

Try…Catch ステートメントでは、複数の Catch ステートメントを使用できます。You can use more than one Catch statement in a Try…Catch statement. これを行うと、Catch 句の順序は順番に検査されるため、重要になります。If you do this, the order of the Catch clauses is significant because they are examined in order. 例外は、特殊性の高い順にキャッチしてください。Catch the more specific exceptions before the less specific ones.

次の Catch ステートメントの条件は最も限定的ではなく、Exception クラスから派生したすべての例外をキャッチします。The following Catch statement conditions are the least specific, and will catch all exceptions that derive from the Exception class. 通常は、必要なすべての例外をキャッチした後、これらのバリエーションのいずれかを Try...Catch...Finally 構造の最後の Catch ブロックとして使用する必要があります。You should ordinarily use one of these variations as the last Catch block in the Try...Catch...Finally structure, after catching all the specific exceptions you expect. 制御フローは、これらのいずれかのバリエーションに従う Catch ブロックにはできません。Control flow can never reach a Catch block that follows either of these variations.

  • typeExceptionです。例: Catch ex As ExceptionThe type is Exception, for example: Catch ex As Exception

  • ステートメントには exception の変数がありません。例: CatchThe statement has no exception variable, for example: Catch

Try…Catch…Finally ステートメントが別の Try ブロックに入れ子になっている場合、Visual Basic は、最も内側の Try ブロック内の各 Catch ステートメントをまず調べます。When a Try…Catch…Finally statement is nested in another Try block, Visual Basic first examines each Catch statement in the innermost Try block. 一致する Catch ステートメントが見つからない場合は、外側の Try…Catch…Finally ブロックの Catch ステートメントに進みます。If no matching Catch statement is found, the search proceeds to the Catch statements of the outer Try…Catch…Finally block.

Try ブロックのローカル変数は、個別のブロックであるため、Catch ブロックでは使用できません。Local variables from a Try block are not available in a Catch block because they are separate blocks. 複数のブロックで変数を使用する場合は、Try...Catch...Finally 構造体の外で変数を宣言します。If you want to use a variable in more than one block, declare the variable outside the Try...Catch...Finally structure.

ヒント

Try…Catch…Finally ステートメントは、IntelliSense コードスニペットとして使用できます。The Try…Catch…Finally statement is available as an IntelliSense code snippet. コードスニペットマネージャーで、[コードパターン-If] を展開し、[ Catch]、[プロパティ] などをクリックして、 [エラー処理 (例外)] をクリックします。In the Code Snippets Manager, expand Code Patterns - If, For Each, Try Catch, Property, etc, and then Error Handling (Exceptions). 詳細については、「 Code Snippets」を参照してください。For more information, see Code Snippets.

Finally ブロックFinally block

Try 構造体を終了する前に実行する必要のあるステートメントが1つ以上ある場合は、Finally ブロックを使用します。If you have one or more statements that must run before you exit the Try structure, use a Finally block. 制御は、Try…Catch 構造から渡される直前に Finally ブロックに渡されます。Control passes to the Finally block just before it passes out of the Try…Catch structure. これは、Try 構造内のどこかで例外が発生した場合でも当てはまります。This is true even if an exception occurs anywhere inside the Try structure.

Finally ブロックは、例外が発生した場合でも実行する必要があるコードを実行する場合に便利です。A Finally block is useful for running any code that must execute even if there is an exception. コントロールは、Try...Catch ブロックの終了方法に関係なく、Finally ブロックに渡されます。Control is passed to the Finally block regardless of how the Try...Catch block exits.

Finally ブロック内のコードは、コードが Try または Catch ブロックで Return ステートメントを検出した場合でも実行されます。The code in a Finally block runs even if your code encounters a Return statement in a Try or Catch block. 次の場合、コントロールは、Try または Catch ブロックから対応する Finally ブロックに渡されません。Control does not pass from a Try or Catch block to the corresponding Finally block in the following cases:

実行を明示的に Finally ブロックに転送することは無効です。It is not valid to explicitly transfer execution into a Finally block. 例外を除き、Finally ブロックの実行を転送することはできません。Transferring execution out of a Finally block is not valid, except through an exception.

Try ステートメントに少なくとも1つの Catch ブロックが含まれていない場合は、Finally ブロックが含まれている必要があります。If a Try statement does not contain at least one Catch block, it must contain a Finally block.

ヒント

特定の例外をキャッチする必要がない場合、Using ステートメントは、ブロックを終了する方法に関係なく、Try…Finally ブロックのように動作し、リソースの破棄を保証します。If you do not have to catch specific exceptions, the Using statement behaves like a Try…Finally block, and guarantees disposal of the resources, regardless of how you exit the block. これは、ハンドルされない例外が発生した場合でも同様です。This is true even with an unhandled exception. 詳細については、「sing ステートメント」を参照してください。For more information, see Using Statement.

Exception 引数Exception argument

Catch block exception 引数は Exception クラスのインスタンス、または Exception クラスから派生したクラスです。The Catch block exception argument is an instance of the Exception class or a class that derives from the Exception class. Exception クラスのインスタンスは、Try ブロックで発生したエラーに対応します。The Exception class instance corresponds to the error that occurred in the Try block.

Exception オブジェクトのプロパティは、例外の原因と場所を特定するのに役立ちます。The properties of the Exception object help to identify the cause and location of an exception. たとえば、StackTrace プロパティには、例外の原因となったメソッドが一覧表示され、コード内でエラーが発生した場所を見つけるのに役立ちます。For example, the StackTrace property lists the called methods that led to the exception, helping you find where the error occurred in the code. Message は、例外を説明するメッセージを返します。Message returns a message that describes the exception. HelpLink は、関連付けられているヘルプファイルへのリンクを返します。HelpLink returns a link to an associated Help file. InnerException は、現在の例外の原因となった Exception オブジェクトを返すか、元の Exceptionがない場合は Nothing を返します。InnerException returns the Exception object that caused the current exception, or it returns Nothing if there is no original Exception.

Try…Catchステートメントを使用に関する注意点Considerations when using a Try…Catch statement

Try…Catch ステートメントのみを使用して、異常なプログラムイベントまたは予期しないプログラムイベントの発生を通知します。Use a Try…Catch statement only to signal the occurrence of unusual or unanticipated program events. これには、次のような理由があります。Reasons for this include the following:

  • 実行時に例外をキャッチするとオーバーヘッドが増加するため、例外を回避するための事前チェックよりも低速になる可能性があります。Catching exceptions at runtime creates additional overhead, and is likely to be slower than pre-checking to avoid exceptions.

  • Catch ブロックが正しく処理されない場合、例外はユーザーに正しく報告されない可能性があります。If a Catch block is not handled correctly, the exception might not be reported correctly to users.

  • 例外処理を使用すると、プログラムがより複雑になります。Exception handling makes a program more complex.

常に、発生する可能性がある条件をチェックするために Try…Catch ステートメントは必要ありません。You do not always need a Try…Catch statement to check for a condition that is likely to occur. 次の例では、ファイルが存在するかどうかを確認してから開こうとします。The following example checks whether a file exists before trying to open it. これにより、OpenText メソッドによってスローされた例外をキャッチする必要がなくなります。This reduces the need for catching an exception thrown by the OpenText method.

Private Sub TextFileExample(ByVal filePath As String)

    ' Verify that the file exists.
    If System.IO.File.Exists(filePath) = False Then
        Console.Write("File Not Found: " & filePath)
    Else
        ' Open the text file and display its contents.
        Dim sr As System.IO.StreamReader =
            System.IO.File.OpenText(filePath)

        Console.Write(sr.ReadToEnd)

        sr.Close()
    End If
End Sub

スレッドセーフなログ記録と適切なメッセージのどちらを使用しても、Catch ブロック内のコードがユーザーに例外を正しく報告できることを確認します。Ensure that code in Catch blocks can properly report exceptions to users, whether through thread-safe logging or appropriate messages. それ以外の場合、例外は不明なままになる可能性があります。Otherwise, exceptions might remain unknown.

非同期メソッドAsync methods

非同期修飾子を使用してメソッドをマークした場合は、メソッドでAwait演算子を使用できます。If you mark a method with the Async modifier, you can use the Await operator in the method. Await 演算子を持つステートメントは、待機中のタスクが完了するまでメソッドの実行を中断します。A statement with the Await operator suspends execution of the method until the awaited task completes. このタスクは、進行中の作業を表します。The task represents ongoing work. Await オペレーターに関連付けられているタスクが完了すると、同じ方法で実行が再開されます。When the task that's associated with the Await operator finishes, execution resumes in the same method. 詳細については、「非同期プログラムの制御フロー」を参照してください。For more information, see Control Flow in Async Programs.

非同期メソッドによって返されるタスクは、未処理の例外によって完了したことを示す、faulted 状態で終了することがあります。A task returned by an Async method may end in a faulted state, indicating that it completed due to an unhandled exception. また、タスクは取り消された状態で終了することもあります。その結果、await 式から OperationCanceledException がスローされます。A task may also end in a canceled state, which results in an OperationCanceledException being thrown out of the await expression. いずれかの種類の例外をキャッチするには、タスクに関連付けられている Await 式を Try ブロックに配置し、Catch ブロックで例外をキャッチします。To catch either type of exception, place the Await expression that's associated with the task in a Try block, and catch the exception in the Catch block. 例については、このトピックの後半で説明します。An example is provided later in this topic.

複数の例外がエラーの原因になっているため、タスクが faulted 状態になることがあります。A task can be in a faulted state because multiple exceptions were responsible for its faulting. たとえば、タスクは Task.WhenAll の呼び出しの結果になることがあります。For example, the task might be the result of a call to Task.WhenAll. このようなタスクを待機すると、キャッチされた例外は例外の1つにすぎないため、どの例外がキャッチされるかを予測することはできません。When you await such a task, the caught exception is only one of the exceptions, and you can't predict which exception will be caught. 例については、このトピックの後半で説明します。An example is provided later in this topic.

Await 式は、Catch ブロックまたは Finally ブロック内には指定できません。An Await expression can't be inside a Catch block or Finally block.

IteratorsIterators

反復子メソッドまたはGetアクセサーは、コレクションに対するカスタム イテレーションを実行します。An iterator function or Get accessor performs a custom iteration over a collection. 反復子はYieldステートメントを使用して、コレクションの各要素を一度に 1 つずつ返します。An iterator uses a Yield statement to return each element of the collection one at a time. For Each...Next ステートメントを使用して反復子メソッドを呼び出します。You call an iterator function by using a For Each...Next Statement.

YieldTryブロック内に置くことができます。A Yield statement can be inside a Try block. Yieldステートメントを含むTryブロックは、Catchブロックを持つことができ、そして、Finallyブロックを持つことができます。A Try block that contains a Yield statement can have Catch blocks, and can have a Finally block. 例については、反復子Tryブロックを参照してください。See the "Try Blocks in Visual Basic" section of Iterators for an example.

Yieldステートメントは、CatchブロックまたはFinallyブロック内で使用できません。A Yield statement cannot be inside a Catch block or a Finally block.

For Each本体 (反復子メソッドの外側)が例外をスローした場合、反復子メソッド内のCatchブロックは実行されませんが、反復子メソッド内のFinallyブロックは実行されます。If the For Each body (outside of the iterator function) throws an exception, a Catch block in the iterator function is not executed, but a Finally block in the iterator function is executed. 反復子メソッド内のCatchブロックは、反復子メソッド内で発生する例外のみをキャッチします。A Catch block inside an iterator function catches only exceptions that occur inside the iterator function.

部分信頼の状況Partial-trust situations

部分的に信頼された状況 (ネットワーク共有でホストされているアプリケーションなど) では、Try...Catch...Finally は、呼び出しを含むメソッドが呼び出される前に発生したセキュリティ例外をキャッチしません。In partial-trust situations, such as an application hosted on a network share, Try...Catch...Finally does not catch security exceptions that occur before the method that contains the call is invoked. 次の例では、サーバー共有に配置し、そこから実行すると、"SecurityException: Request Failed" というエラーが生成されます。The following example, when you put it on a server share and run from there, produces the error "System.Security.SecurityException: Request Failed." セキュリティ例外の詳細については、SecurityException クラスを参照してください。For more information about security exceptions, see the SecurityException class.

Try
    Process.Start("http://www.microsoft.com")
Catch ex As Exception
    MsgBox("Can't load Web page" & vbCrLf & ex.Message)
End Try

このような部分信頼の場合は、Process.Start ステートメントを別の Subに配置する必要があります。In such a partial-trust situation, you have to put the Process.Start statement in a separate Sub. Sub の最初の呼び出しは失敗します。The initial call to the Sub will fail. これにより、Process.Start を含む Sub が開始され、セキュリティ例外が生成される前に、Try...Catch をキャッチできます。This enables Try...Catch to catch it before the Sub that contains Process.Start is started and the security exception produced.

使用例Examples

Try...Catch...Finallyの構造The structure of Try...Catch...Finally

次の例はTry...Catch...Finallyステートメントの構造を示しています。The following example illustrates the structure of the Try...Catch...Finally statement.

Public Sub TryExample()
    ' Declare variables.
    Dim x As Integer = 5
    Dim y As Integer = 0

    ' Set up structured error handling.
    Try
        ' Cause a "Divide by Zero" exception.
        x = x \ y

        ' This statement does not execute because program
        ' control passes to the Catch block when the
        ' exception occurs.
        MessageBox.Show("end of Try block")
    Catch ex As Exception
        ' Show the exception's message.
        MessageBox.Show(ex.Message)

        ' Show the stack trace, which is a list of methods
        ' that are currently executing.
        MessageBox.Show("Stack Trace: " & vbCrLf & ex.StackTrace)
    Finally
        ' This line executes whether or not the exception occurs.
        MessageBox.Show("in Finally block")
    End Try
End Sub

Try ブロックから呼び出されたメソッドで例外が発生しましたException in a method called from a Try block

次の例では、CreateException メソッドによって NullReferenceExceptionがスローされます。In the following example, the CreateException method throws a NullReferenceException. 例外を生成するコードが Try ブロックに含まれていません。The code that generates the exception is not in a Try block. したがって、CreateException メソッドは例外を処理しません。Therefore, the CreateException method does not handle the exception. RunSample メソッドは、CreateException メソッドの呼び出しが Try ブロック内にあるため、例外を処理します。The RunSample method does handle the exception because the call to the CreateException method is in a Try block.

この例には、いくつかの種類の例外の Catch ステートメントが含まれており、最も一般的なものから順に説明されています。The example includes Catch statements for several types of exceptions, ordered from the most specific to the most general.

Public Sub RunSample()
    Try
        CreateException()
    Catch ex As System.IO.IOException
        ' Code that reacts to IOException.
    Catch ex As NullReferenceException
        MessageBox.Show("NullReferenceException: " & ex.Message)
        MessageBox.Show("Stack Trace: " & vbCrLf & ex.StackTrace)
    Catch ex As Exception
        ' Code that reacts to any other exception.
    End Try
End Sub

Private Sub CreateException()
    ' This code throws a NullReferenceException.
    Dim obj = Nothing
    Dim prop = obj.Name

    ' This code also throws a NullReferenceException.
    'Throw New NullReferenceException("Something happened.")
End Sub

Catch When ステートメントThe Catch When statement

次の例では、Catch When ステートメントを使用して条件式をフィルター処理する方法を示します。The following example shows how to use a Catch When statement to filter on a conditional expression. 条件式が Trueと評価された場合、Catch ブロック内のコードが実行されます。If the conditional expression evaluates to True, the code in the Catch block runs.

Private Sub WhenExample()
    Dim i As Integer = 5

    Try
        Throw New ArgumentException()
    Catch e As OverflowException When i = 5
        Console.WriteLine("First handler")
    Catch e As ArgumentException When i = 4
        Console.WriteLine("Second handler")
    Catch When i = 5
        Console.WriteLine("Third handler")
    End Try
End Sub
' Output: Third handler

入れ子になった Try ステートメントNested Try statements

次の例では、Try ブロックに含まれる Try…Catch ステートメントを使用します。The following example has a Try…Catch statement that is contained in a Try block. 内部 Catch ブロックは、InnerException プロパティが元の例外に設定されている例外をスローします。The inner Catch block throws an exception that has its InnerException property set to the original exception. 外側の Catch ブロックは、独自の例外と内部例外を報告します。The outer Catch block reports its own exception and the inner exception.

Private Sub InnerExceptionExample()
    Try
        Try
            ' Set a reference to a StringBuilder.
            ' The exception below does not occur if the commented
            ' out statement is used instead.
            Dim sb As System.Text.StringBuilder
            'Dim sb As New System.Text.StringBuilder

            ' Cause a NullReferenceException.
            sb.Append("text")
        Catch ex As Exception
            ' Throw a new exception that has the inner exception
            ' set to the original exception.
            Throw New ApplicationException("Something happened :(", ex)
        End Try
    Catch ex2 As Exception
        ' Show the exception.
        Console.WriteLine("Exception: " & ex2.Message)
        Console.WriteLine(ex2.StackTrace)

        ' Show the inner exception, if one is present.
        If ex2.InnerException IsNot Nothing Then
            Console.WriteLine("Inner Exception: " & ex2.InnerException.Message)
            Console.WriteLine(ex2.StackTrace)
        End If
    End Try
End Sub

非同期メソッドの例外処理Exception handling for async methods

次の例では、非同期メソッドの例外処理を示します。The following example illustrates exception handling for async methods. 非同期タスクに適用される例外をキャッチするために、Await 式は呼び出し元の Try ブロックにあり、例外は Catch ブロックでキャッチされます。To catch an exception that applies to an async task, the Await expression is in a Try block of the caller, and the exception is caught in the Catch block.

例外処理を示すために、この例の Throw New Exception 行のコメントを解除します。Uncomment the Throw New Exception line in the example to demonstrate exception handling. 例外は Catch ブロックでキャッチされ、タスクの IsFaulted プロパティは Trueに設定され、タスクの Exception.InnerException プロパティは例外に設定されます。The exception is caught in the Catch block, the task's IsFaulted property is set to True, and the task's Exception.InnerException property is set to the exception.

Throw New OperationCancelledException 行のコメントを解除して、非同期処理を取り消したときに何が起こるかを示します。Uncomment the Throw New OperationCancelledException line to demonstrate what happens when you cancel an asynchronous process. 例外は Catch ブロックでキャッチされ、タスクの IsCanceled プロパティは Trueに設定されます。The exception is caught in the Catch block, and the task's IsCanceled property is set to True. ただし、この例には適用されない条件がある場合、IsFaultedTrue に設定され IsCanceledFalseに設定されます。However, under some conditions that don't apply to this example, IsFaulted is set to True and IsCanceled is set to False.

Public Async Function DoSomethingAsync() As Task
    Dim theTask As Task(Of String) = DelayAsync()

    Try
        Dim result As String = Await theTask
        Debug.WriteLine("Result: " & result)
    Catch ex As Exception
        Debug.WriteLine("Exception Message: " & ex.Message)
    End Try

    Debug.WriteLine("Task IsCanceled: " & theTask.IsCanceled)
    Debug.WriteLine("Task IsFaulted:  " & theTask.IsFaulted)
    If theTask.Exception IsNot Nothing Then
        Debug.WriteLine("Task Exception Message: " &
            theTask.Exception.Message)
        Debug.WriteLine("Task Inner Exception Message: " &
            theTask.Exception.InnerException.Message)
    End If
End Function

Private Async Function DelayAsync() As Task(Of String)
    Await Task.Delay(100)

    ' Uncomment each of the following lines to
    ' demonstrate exception handling.

    'Throw New OperationCanceledException("canceled")
    'Throw New Exception("Something happened.")
    Return "Done"
End Function


' Output when no exception is thrown in the awaited method:
'   Result: Done
'   Task IsCanceled: False
'   Task IsFaulted:  False

' Output when an Exception is thrown in the awaited method:
'   Exception Message: Something happened.
'   Task IsCanceled: False
'   Task IsFaulted:  True
'   Task Exception Message: One or more errors occurred.
'   Task Inner Exception Message: Something happened.

' Output when an OperationCanceledException or TaskCanceledException
' is thrown in the awaited method:
'   Exception Message: canceled
'   Task IsCanceled: True
'   Task IsFaulted:  False

非同期メソッドでの複数の例外の処理Handling multiple exceptions in async methods

次の例では、複数のタスクで複数の例外が発生する可能性がある例外処理について説明します。The following example illustrates exception handling where multiple tasks can result in multiple exceptions. Try ブロックには、返される Task.WhenAll タスクの Await 式が含まれています。The Try block has the Await expression for the task that Task.WhenAll returned. Task.WhenAll が適用される3つのタスクが完了すると、タスクが完了します。The task is complete when the three tasks to which Task.WhenAll is applied are complete.

3 つのタスクでそれぞれ例外が発生します。Each of the three tasks causes an exception. Catch ブロックは、返される Task.WhenAll タスクの Exception.InnerExceptions プロパティで検出された例外を反復処理します。The Catch block iterates through the exceptions, which are found in the Exception.InnerExceptions property of the task that Task.WhenAll returned.

Public Async Function DoMultipleAsync() As Task
    Dim theTask1 As Task = ExcAsync(info:="First Task")
    Dim theTask2 As Task = ExcAsync(info:="Second Task")
    Dim theTask3 As Task = ExcAsync(info:="Third Task")

    Dim allTasks As Task = Task.WhenAll(theTask1, theTask2, theTask3)

    Try
        Await allTasks
    Catch ex As Exception
        Debug.WriteLine("Exception: " & ex.Message)
        Debug.WriteLine("Task IsFaulted: " & allTasks.IsFaulted)
        For Each inEx In allTasks.Exception.InnerExceptions
            Debug.WriteLine("Task Inner Exception: " + inEx.Message)
        Next
    End Try
End Function

Private Async Function ExcAsync(info As String) As Task
    Await Task.Delay(100)

    Throw New Exception("Error-" & info)
End Function

' Output:
'   Exception: Error-First Task
'   Task IsFaulted: True
'   Task Inner Exception: Error-First Task
'   Task Inner Exception: Error-Second Task
'   Task Inner Exception: Error-Third Task

関連項目See also