Await 运算符 (Visual Basic)
应用 Await 运算符于异步方法或 lambda 表达式的一个操作线程挂起方法的执行,直到等待任务完成。任务表示正在进行的工作。
Await 使用的方法必须具有 异步 修饰符。这样,方法是使用 Async 修饰符和通常包含一个或多 Await 表达式,引用 异步方法。
说明 |
---|
Async 和 Await 关键字在 Visual Studio 2012 中引入)。有关在该版本的新增功能的信息,请参见 Visual Studio 2012 中的新增功能。 有关异步编程的介绍,请参见 使用 Async 和 Await 的异步编程(C# 和 Visual Basic)。 |
通常,的任务将 Await 运算符是从调用的返回值设置为实现,基于任务的异步模式也就是说,Task 或 Task<TResult>的方法。
在下面的代码中,HttpClient 方法 GetByteArrayAsync 返回 getContentsTask,Task(Of Byte())。在操作完成时,任务是承诺生成实际字节数组。Await 运算符在 SumPageSizesAsync 会应用于 getContentsTask 挂起执行,直到 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 表达式的主体只能发生。这个术语 等待 作为一个仅关键字在该上下文。在其他地方,则将该说明符解释为标识符。在异步方法或 lambda 表达式中,Await 表达式在查询表达式不能出现错误,则 catch 或 finally 块 try…catch…finally 语句,在 For 或 For Each 循环的循环控制变量表达式,或者在 SyncLock 语句的主体。
异常
大多数异步方法返回 Task 或 Task<TResult>。返回的任务的属性传播有关其状态和历史记录的信息,例如任务是否已完成,异步方法是否引发异常或已取消,以及最终结果是。Await 运算符访问这些属性。
如果等待导致异常的一个任务返回的异步方法,Await 运算符再次引发异常。
如果等待取消的一个任务返回的异步方法,Await 运算符再次引发 OperationCanceledException。
在出错状态的单一任务可能反映出多个异常。例如,任务可能为调用的结果。Task.WhenAll。当您等待此类任务,异常的等待操作再次引发只有一个。但是,您无法预测哪些异常来重新引发。
在中的错误处理异步方法的示例,请参见 Try...Catch...Finally 语句 (Visual Basic)。
示例
以下 windows 窗体示例阐释如何在异步方法的 Await,WaitAsynchronouslyAsync。对比度该方法的行为与 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)