Await 运算符 (Visual Basic)

您在异步方法或 lambda 表达式应用 Await 运算符用以延迟该操作直到所等待任务完成。 表示正在进行的工作的任务。

使用 Await 的方法必须具有 Async 修饰符修饰。 由使用 Async 修饰符定义且通常包含一个或多个 Await 表达式的此类方法称为异步方法。

备注

在 Visual Studio 2012 中引入 Async 和 Await 关键字。有关异步编程的介绍,请参见 使用 Async 和 Await 的异步编程(C# 和 Visual Basic)

应用 Await 运算符的任务的返回值通常是调用一个基于任务的异步模式 的方法,即 TaskTask.

在以下代码中,HttpClient 方法 GetByteArrayAsync 返回 getContentsTask,一个 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

重要

有关完整的示例,请参见演练:使用 Async 和 Await 访问 Web(C# 和 Visual Basic)。您可以在 Microsoft 网站上从开发人员代码示例中下载示例。此示例在 AsyncWalkthrough_HttpClient 项目中。

如果 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 修饰符标记的一个立即封闭方法体或 lambda 表达式中。 Await术语在该上下文中仅用作关键字。 在其他地方,其解释为标识符。 在异步方法或 lambda 表达式中,Await 表达式不能在查询表达式,try…catch…finally 语句中的 catch 或 finally 块中 ,循环控制变量表达式 For 或 For Each 的循环中,或者 SyncLock 语句的主体中出现。

异常

大多数异步方法返回 TaskTask。 返回任务的属性承载有关其状态和历史记录的信息,例如任务是否已完成,异步方法是否引发异常或已取消,以及最终结果如何。 Await 运算符访问那些属性。

如果等待导致异常的任务返回的异步方法,Await 运算符会再次引发异常。

如果等待的返回任务的异步方法取消了,Await 运算符将再次引发 OperationCanceledException

处于出错状态的单个任务可能反映出多个异常。例如,该任务可能是对 Task.WhenAll 调用的结果。 当您等待此类任务时,await 操作只能再次引发异常中的一个。 但是,您不能预测哪些异常是重新引发的。

有关错误处理同步方法的示例,请参见 Try...Catch...Finally 语句 (Visual Basic)

示例

以下 Windows Forms 示例说明了异步方法 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

请参见

任务

演练:使用 Async 和 Await 访问 Web(C# 和 Visual Basic)

参考

Async (Visual Basic)

概念

使用 Async 和 Await 的异步编程(C# 和 Visual Basic)