Await 運算子 (Visual Basic)Await Operator (Visual Basic)

您在非同步方法或 Lambda 運算式的運算元中套用 Await 運算子,讓方法暫停執行,直到等候的工作完成。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.

使用 Await 的方法必須有Async修飾詞。The method in which Await is used must have an Async modifier. 這種方法是使用 Async 修飾詞所定義,且通常包含一或多個 Await 運算式,我們稱之為「非同步方法」。Such a method, defined by using the Async modifier, and usually containing one or more Await expressions, is referred to as an async method.

注意

AsyncAwait 關鍵字是在 Visual Studio 2012 中引入。The Async and Await keywords were introduced in Visual Studio 2012. 如需非同步程式設計的簡介,請參閱使用 async 和 Await 進行非同步程式設計For an introduction to async programming, see Asynchronous Programming with Async and Await.

一般來說,您套用 Await 運算子的工作,就是呼叫方法的傳回值,該方法會執行以工作為基礎的非同步模式,也就是 TaskTask<TResult>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>.

在下列程式碼中,HttpClient 方法 GetByteArrayAsync 會傳回 getContentsTask,也就是 Task(Of Byte())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. Await 運算子會套用至 getContentsTask 以暫停在 SumPageSizesAsync 中執行,直到 getContentsTask 完成。The Await operator is applied to getContentsTask to suspend execution in SumPageSizesAsync until getContentsTask is complete. 同時,控制權會返回 SumPageSizesAsync 的呼叫端。In the meantime, control is returned to the caller of SumPageSizesAsync. getContentsTask 完成之後,Await 運算式會評估為位元組陣列。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

重要

如需完整範例,請參閱逐步解說:使用 async 和 await 存取 WebFor the complete example, see Walkthrough: Accessing the Web by Using Async and Await. 您可以從 Microsoft 網站的開發人員程式碼範例 下載此範例。You can download the sample from Developer Code Samples on the Microsoft website. 此範例位於 AsyncWalkthrough_HttpClient 專案中。The example is in the AsyncWalkthrough_HttpClient project.

如果將 Await 套用至傳回 Task(Of TResult) 之方法呼叫的結果,則 Await 運算式的類型為 TResult。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. 如果 Await 套用至傳回 Task 之方法呼叫的結果,則 Await 運算式不會傳回值。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()

Await 運算式或陳述式不會封鎖其執行所在的執行緒。An Await expression or statement does not block the thread on which it is executing. 但是它會造成編譯器將 Await 運算式之後的其餘非同步方法註冊為所等候工作的接續。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.

Await 運算式可能只會在 Async 修飾詞所標示之立即封入方法或 Lambda 運算式主體中發生。An Await expression can occur only in the body of an immediately enclosing method or lambda expression that is marked by an Async modifier. Await一詞僅作為該內容中的關鍵字。The term Await serves as a keyword only in that context. 在其他內容中,它會解譯為識別項。Elsewhere, it is interpreted as an identifier. 在非同步方法或 lambda 運算式中,Await 運算式不能出現在查詢運算式中、Try 的 catchfinally 區塊中。 Catch 。Finally語句,在 ForFor Each 迴圈的迴圈控制變數運算式中,或在SyncLock語句的主體中。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

大部分的非同步方法會傳回 TaskTask<TResult>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. Await 運算子存取這些屬性。The Await operator accesses those properties.

如果您在等候工作傳回非同步方法時導致例外狀況,Await 運算子會重新擲回例外狀況。If you await a task-returning async method that causes an exception, the Await operator rethrows the exception.

如果您等候已取消的工作傳回非同步方法,則 Await 運算子會重新擲回 OperationCanceledExceptionIf 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. 例如,工作可能是對 Task.WhenAll 呼叫的結果。For example, the task might be the result of a call to Task.WhenAll. 當您等候這類工作時,await 作業只會重新擲回其中一個例外狀況。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.

如需非同步方法中錯誤處理的範例,請參閱嘗試 。Catch 。Finally 語句For examples of error handling in async methods, see Try...Catch...Finally Statement.

範例Example

下列 Windows Form 範例說明如何在非同步方法 WaitAsynchronouslyAsync 中使用 AwaitThe following Windows Forms example illustrates the use of Await in an async method, WaitAsynchronouslyAsync. 請對照該方法的行為與 WaitSynchronously 的行為。Contrast the behavior of that method with the behavior of WaitSynchronously. 若沒有 Await 運算子,儘管在定義中使用 WaitSynchronously 修飾詞並在主體中呼叫 AsyncThread.Sleep 仍會以同步方式執行。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

請參閱See also