您可以將運算子套用 Await 至異步方法或 Lambda 表達式中的作數,以暫停方法的執行,直到等候的工作完成為止。 工作代表進行中的工作。
使用的方法 Await 必須具有 Async 修飾詞。 使用 修飾詞所定義的 Async 這類方法,通常包含一或多個 Await 表達式,稱為 異步方法。
備註
和 AsyncAwait 關鍵詞是在 Visual Studio 2012 中引進的。 如需異步程式設計的簡介,請參閱 使用 Async 和 Await 進行異步程序設計。
一般而言,您套用 Await 運算符的工作是呼叫 方法的傳回值,這個方法會實作 Task-Based 異步模式,也就是 Task 或 Task<TResult>。
在下列程式代碼中 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。 您可以從 .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 Lambda 運算式主體中。
Await 一詞只做為該內容中的關鍵詞。 在其他地方,它會解譯為標識符。 在 方法或 Lambda 表達式內Async,Await表達式不能發生在查詢表達式、CatchTry... 的 或 Finally 區塊中...抓住。。。Finally 語句,在 或 For Each 迴圈的For迴圈控件變數表達式中,或在 SyncLock 語句主體中。
例外狀況
大部分異步方法都會傳回 Task 或 Task<TResult>。 傳回工作的屬性會包含其狀態和歷程記錄的相關信息,例如工作是否已完成、異步方法是否造成例外狀況或已取消,以及最終結果為何。 運算子 Await 會存取這些屬性。
如果您等候導致例外狀況的工作傳回異步方法, Await 運算符會重新擲回例外狀況。
如果您要取消的工作傳回異步方法, Await 運算子會重新擲 OperationCanceledException回 。
處於錯誤狀態的單一工作可以反映多個例外狀況。 例如,工作可能是對 Task.WhenAll 呼叫的結果。 當您等候這類工作時,await 作業只會重新擲回其中一個例外狀況。 不過,您無法預測哪些例外狀況已重新擲回。
如需異步方法中錯誤處理的範例,請參閱 試用...抓住。。。Finally 語句。
範例
下列 Windows Forms 範例說明如何在 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