Await Operator (Visual Basic)
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.
The method in which Await
is used must have an Async modifier. Such a method, defined by using the Async
modifier, and usually containing one or more Await
expressions, is referred to as an async method.
Note
The Async
and Await
keywords were introduced in Visual Studio 2012. For an introduction to async programming, see Asynchronous Programming with Async and Await.
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>.
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. The Await
operator is applied to getContentsTask
to suspend execution in SumPageSizesAsync
until getContentsTask
is complete. In the meantime, control is returned to the caller of SumPageSizesAsync
. 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
Important
For the complete example, see Walkthrough: Accessing the Web by Using Async and Await. You can download the sample from the .NET Sample Browser. The example code is in the SerialAsyncExample project.
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. 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()
An Await
expression or statement does not block the thread on which it is executing. 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.
An Await
expression can occur only in the body of an immediately enclosing method or lambda expression that is marked by an Async
modifier. The term Await serves as a keyword only in that context. Elsewhere, it is interpreted as an identifier. 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
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. The Await
operator accesses those properties.
If you await a task-returning async method that causes an exception, the Await
operator rethrows the exception.
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. For example, the task might be the result of a call to Task.WhenAll. 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.
For examples of error handling in async methods, see Try...Catch...Finally Statement.
Example
The following Windows Forms example illustrates the use of Await
in an async method, WaitAsynchronouslyAsync
. Contrast the behavior of that method with the behavior of WaitSynchronously
. 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