待機中のタスクが完了するまでメソッドの実行を中断するには、非同期メソッドまたはラムダ式のオペランドに Await
演算子を適用します。 タスクは、進行中の作業を表します。
Await
を使用するメソッドには、Async 修飾子が必要です。 このようなメソッドは、 Async
修飾子を使用して定義され、通常は 1 つ以上の Await
式を含み、 非同期メソッドと呼ばれます。
注
Async
キーワードとAwait
キーワードは、Visual Studio 2012 で導入されました。 非同期プログラミングの概要については、「Async と Await を使用した非同期プログラミング」を参照してください。
通常、Await
演算子を適用するタスクは、Task-Based 非同期パターン (TaskまたはTask<TResult>) を実装するメソッドの呼び出しからの戻り値です。
次のコードでは、HttpClient メソッドGetByteArrayAsyncgetContentsTask
Task(Of Byte())
を返します。 このタスクは、操作が完了したときに実際のバイト配列を生成する約束です。
Await
演算子は、getContentsTask
が完了するまでSumPageSizesAsync
での実行を中断するために、getContentsTask
に適用されます。 それまでの間は、 SumPageSizesAsync
の呼び出し元に制御が返されます。
getContentsTask
が完了すると、Await
式はバイト配列に評価されます。
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
Von Bedeutung
完全な例については、「 チュートリアル: Async と Await を使用した Web へのアクセス」を参照してください。 .NET サンプル ブラウザーからサンプルをダウンロードできます。 コード例は 、SerialAsyncExample プロジェクトにあります。
Await
Task(Of TResult)
を返すメソッド呼び出しの結果に適用される場合、Await
式の型は TResult です。
Await
Task
を返すメソッド呼び出しの結果に適用された場合、Await
式は値を返しません。 次の例は、その違いを示しています。
' 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
式またはステートメントは、それが実行されているスレッドをブロックしません。 代わりに、コンパイラは、待機中のタスクの継続として、 Await
式の後に非同期メソッドの残りの部分をサインアップします。 次に、非同期メソッドの呼び出し元に制御が戻ります。 タスクが完了すると、タスクは継続を呼び出し、非同期メソッドの実行は中断したところから再開されます。
Await
式は、Async
修飾子でマークされた、すぐに囲むメソッドまたはラムダ式の本体でのみ発生します。
Await という用語は、そのコンテキストでのみキーワードとして機能します。 それ以外の場所では、識別子として解釈されます。
Async
メソッドまたはラムダ式内では、Await
式は、クエリ式、try のCatch
ブロック、または Finally
ブロックでは使用できません。捕まえる。。。最後に、For
またはFor Each
ループのループ コントロール変数式、または SyncLock ステートメントの本体内のステートメント。
例外
ほとんどの非同期メソッドは、 Task または Task<TResult>を返します。 返されるタスクのプロパティには、タスクが完了しているかどうか、非同期メソッドが例外を発生させたかキャンセルされたか、最終的な結果など、その状態と履歴に関する情報が含まれます。
Await
演算子は、これらのプロパティにアクセスします。
例外を引き起こすタスクを返す非同期メソッドを待機している場合、 Await
演算子は例外を再スローします。
取り消されたタスクを返す非同期メソッドを待機すると、 Await
演算子は OperationCanceledExceptionを再スローします。
障害が発生した状態の 1 つのタスクには、複数の例外が反映される場合があります。 たとえば、タスクは、 Task.WhenAllの呼び出しの結果である可能性があります。 このようなタスクを待機すると、待機操作は例外の 1 つだけを再スローします。 ただし、どの例外が再スローされているかを予測することはできません。
非同期メソッドでのエラー処理の例については、「 Try..」を参照してください。捕まえる。。。Finally ステートメント。
例
次の Windows フォームの例は、非同期メソッド (WaitAsynchronouslyAsync
) でのAwait
の使用を示しています。 そのメソッドの動作と WaitSynchronously
の動作を比較します。
Await
演算子を使用しない場合、WaitSynchronously
は定義でAsync
修飾子を使用し、その本体でThread.Sleepを呼び出した場合でも同期的に実行されます。
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
こちらも参照ください
.NET