Await 运算符 (Visual Basic)

Await 运算符应用于异步方法或 lambda 表达式中的作数,以暂停方法的执行,直到等待的任务完成。 任务表示正在进行的工作。

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

注释

Visual Studio 2012 中引入了关键字 AsyncAwait 关键字。 有关异步编程的简介,请参阅 使用 Async 和 Await 进行异步编程

通常,应用Await运算符的任务是从对实现 Task-Based 异步模式(即TaskTask<TResult>或异步模式)的方法的调用返回值。

在以下代码中,该方法HttpClientGetByteArrayAsync返回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。 可以从 .NET 示例浏览器下载示例。 示例代码位于 SerialAsyncExample 项目中。

如果 Await 应用于返回 a Task(Of TResult)的方法调用的结果,则 Await 表达式的类型为 TResult。 如果 Await 应用于返回 a 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 仅在该上下文中用作关键字。 在其他地方,它被解释为标识符。 在Async方法或 lambda 表达式中,Await表达式不能出现在查询表达式、Try... 的或Finally块中Catch...抓住。。。最后,在循环控件变量表达式中ForFor Each,或在 SyncLock 语句的正文中。

例外

大多数异步方法返回或 TaskTask<TResult>。 返回的任务的属性包含有关其状态和历史记录的信息,例如任务是否完成、异步方法是否导致异常或已取消,以及最终结果是什么。 Await操作员访问这些属性。

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

如果等待已取消的任务返回异步方法,则 Await 运算符将重新引发一个 OperationCanceledException

处于故障状态的单个任务可以反映多个异常。 例如,该任务可能是对 Task.WhenAll. 的调用的结果。 等待此类任务时,await作只重新引发其中一个异常。 但是,无法预测哪些异常被重新引发。

有关异步方法中的错误处理示例,请参阅 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

另请参阅