Await 演算子 (Visual Basic)Await Operator (Visual Basic)

Await 演算子は、非同期のメソッドまたはラムダ式のオペランドに適用されて、待機中のタスクが完了するまでメソッドの実行を中断します。You apply the Await operator to an operand in an asynchronous method or lambda expression to suspend execution of the method until the awaited task completes. このタスクは、進行中の作業を表します。The task represents ongoing work.

Await を使用するメソッドには、 Async修飾子が必要です。The method in which Await is used must have an Async modifier. このようなメソッド (Async 修飾子を使用して定義され、通常 1 つ以上の Await 式を含むメソッド) を "非同期メソッド" と呼びます。Such a method, defined by using the Async modifier, and usually containing one or more Await expressions, is referred to as an async method.

注意

Async キーワードおよび Await キーワードは、Visual Studio 2012 で導入されました。The Async and Await keywords were introduced in Visual Studio 2012. 非同期プログラミングの概要については、「 async および Await を使用した非同期プログラミング」を参照してください。For an introduction to async programming, see Asynchronous Programming with Async and Await.

通常、Await 演算子を適用するタスクは、タスクベースの非同期パターン、つまり、Task または Task<TResult>を実装するメソッドの呼び出しからの戻り値です。Typically, the task to which you apply the Await operator is the return value from a call to a method that implements the Task-Based Asynchronous Pattern, that is, a Task or a Task<TResult>.

次のコードでは、HttpClient メソッドの GetByteArrayAsyncgetContentsTask (Task(Of Byte())) を返します。In the following code, the HttpClient method GetByteArrayAsync returns getContentsTask, a Task(Of Byte()). これにより、操作が完了したときに実際のバイト配列が生成されることが保証されます。The task is a promise to produce the actual byte array when the operation is complete. Await 演算子が getContentsTask に適用されているため、SumPageSizesAsync が完了するまで getContentsTask の実行が中断されます。The Await operator is applied to getContentsTask to suspend execution in SumPageSizesAsync until getContentsTask is complete. その間、コントロールは SumPageSizesAsync の呼び出し元に戻されます。In the meantime, control is returned to the caller of SumPageSizesAsync. getContentsTask が終了すると、Await 式がバイト配列に評価されます。When getContentsTask is finished, the Await expression evaluates to a byte array.

Private Async Function SumPageSizesAsync() As Task

    ' To use the HttpClient type in desktop apps, you must include a using directive and add a
    ' reference for the System.Net.Http namespace.
    Dim client As HttpClient = New HttpClient()
    ' . . .
    Dim getContentsTask As Task(Of Byte()) = client.GetByteArrayAsync(url)
    Dim urlContents As Byte() = Await getContentsTask

    ' Equivalently, now that you see how it works, you can write the same thing in a single line.
    'Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)
    ' . . .
End Function

重要

完全な例については、「チュートリアル: Async と Await を使用した Web へのアクセス」をご覧ください。For the complete example, see Walkthrough: Accessing the Web by Using Async and Await. Microsoft Web サイトの開発者コード サンプルからサンプルをダウンロードできます。You can download the sample from Developer Code Samples on the Microsoft website. この例は AsyncWalkthrough_HttpClient プロジェクトにあります。The example is in the AsyncWalkthrough_HttpClient project.

Await を返すメソッド呼び出しの結果に Task(Of TResult) が適用されている場合、Await 式の型は TResult になります。If Await is applied to the result of a method call that returns a Task(Of TResult), the type of the Await expression is TResult. Await を返すメソッド呼び出しの結果に Task が適用されている場合、Await 式は値を返しません。If Await is applied to the result of a method call that returns a Task, the Await expression doesn't return a value. この違いを次の例に示します。The following example illustrates the difference.

' Await used with a method that returns a Task(Of TResult).
Dim result As TResult = Await AsyncMethodThatReturnsTaskTResult()

' Await used with a method that returns a Task.
Await AsyncMethodThatReturnsTask()

Await 式またはステートメントは、自身が実行されているスレッドをブロックするのではなく、An Await expression or statement does not block the thread on which it is executing. 非同期メソッドの残りの部分が待機中のタスクの継続として Await 式の後に登録されるようにします。Instead, it causes the compiler to sign up the rest of the async method, after the Await expression, as a continuation on the awaited task. これによって、コントロールは非同期のメソッドの呼び出し元に戻されます。Control then returns to the caller of the async method. タスクが完了すると、継続が呼び出され、中断したところから非同期メソッドの実行が再開されます。When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.

Await 式は、Async 修飾子で修飾されたすぐ外側のメソッドまたはラムダ式の本体でのみ使用できます。An Await expression can occur only in the body of an immediately enclosing method or lambda expression that is marked by an Async modifier. Awaitという用語は、そのコンテキストでのみキーワードとして機能します。The term Await serves as a keyword only in that context. 他の場所では、識別子として解釈されます。Elsewhere, it is interpreted as an identifier. Async メソッドまたはラムダ式内では、クエリ式に Await 式を指定することはできません。そのためには、catch または finally ブロックを指定してください. .キャッチ...Finallyステートメント、For または For Each ループのループ制御変数式、またはSyncLockステートメントの本体。Within the async method or lambda expression, an Await expression cannot occur in a query expression, in the catch or finally block of a Try…Catch…Finally statement, in the loop control variable expression of a For or For Each loop, or in the body of a SyncLock statement.

例外Exceptions

大半の非同期メソッドは、Task または Task<TResult> を返します。Most async methods return a Task or Task<TResult>. 返されるタスクのプロパティには、タスクが完了しているかどうか、非同期メソッドで例外または取り消しが発生したかどうか、最終結果など、その状態および履歴に関する情報が含まれます。The properties of the returned task carry information about its status and history, such as whether the task is complete, whether the async method caused an exception or was canceled, and what the final result is. Await 演算子は、これらのプロパティにアクセスします。The Await operator accesses those properties.

タスクを返す非同期メソッドを待機しているときにそのメソッドで例外が発生した場合、Await 演算子はその例外を再スローします。If you await a task-returning async method that causes an exception, the Await operator rethrows the exception.

タスクを返す非同期メソッドを待機しているときにそのメソッドがキャンセルされた場合、Await 演算子は OperationCanceledException を再スローします。If you await a task-returning async method that is canceled, the Await operator rethrows an OperationCanceledException.

障害の発生した状態にある単一のタスクで、複数の例外が反映される場合があります。A single task that is in a faulted state can reflect multiple exceptions. たとえば、タスクは Task.WhenAll の呼び出しの結果になることがあります。For example, the task might be the result of a call to Task.WhenAll. このようなタスクを待機すると、await 操作によって 1 つの例外のみが再スローされます。When you await such a task, the await operation rethrows only one of the exceptions. ただし、どの例外が再スローされるかを予測することはできません。However, you can't predict which of the exceptions is rethrown.

非同期メソッドのエラー処理の例については、「Try...」を参照してください。 キャッチ...Finally ステートメントFor examples of error handling in async methods, see Try...Catch...Finally Statement.

使用例Example

次に示す Windows フォームの例では、Await という非同期メソッドで WaitAsynchronouslyAsync が使用されています。The following Windows Forms example illustrates the use of Await in an async method, WaitAsynchronouslyAsync. このメソッドの動作と WaitSynchronously の動作の違いを確認します。Contrast the behavior of that method with the behavior of WaitSynchronously. WaitSynchronously には Await 演算子がないため、定義で Async 修飾子が使用されていて、本体で Thread.Sleep が呼び出されているにもかかわらず、同期的に実行されます。Without an Await operator, WaitSynchronously runs synchronously despite the use of the Async modifier in its definition and a call to Thread.Sleep in its body.

Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    ' Call the method that runs asynchronously.
    Dim result As String = Await WaitAsynchronouslyAsync()

    ' Call the method that runs synchronously.
    'Dim result As String = Await WaitSynchronously()

    ' Display the result.
    TextBox1.Text &= result
End Sub

' The following method runs asynchronously. The UI thread is not
' blocked during the delay. You can move or resize the Form1 window
' while Task.Delay is running.
Public Async Function WaitAsynchronouslyAsync() As Task(Of String)
    Await Task.Delay(10000)
    Return "Finished"
End Function

' The following method runs synchronously, despite the use of Async.
' You cannot move or resize the Form1 window while Thread.Sleep
' is running because the UI thread is blocked.
Public Async Function WaitSynchronously() As Task(Of String)
    ' Import System.Threading for the Sleep method.
    Thread.Sleep(10000)
    Return "Finished"
End Function

参照See also