Оператор Await (Visual Basic)Await Operator (Visual Basic)

Оператор 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.

Примечание

Ключевые слова Async и Await появились в 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, является возвращаемым значением из вызова метода, реализующего асинхронную модель на основе задач, то есть Task или Task<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.For the complete example, see Walkthrough: Accessing the Web by Using Async and Await. Вы можете скачать этот пример в разделе Примеры кода для разработчиков на веб-сайте Майкрософт.You can download the sample from Developer Code Samples on the Microsoft website. Этот пример представлен в проекте AsyncWalkthrough_HttpClient.The example is in the AsyncWalkthrough_HttpClient project.

Если к результату вызова метода, возвращающего Task(Of TResult), применяется Await, типом выражения 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()

@No__t_0 выражение или оператор не блокирует поток, в котором он выполняется.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.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. В асинхронном методе или лямбда-выражении выражение Await не может встречаться в выражении запроса, в блоке catch или finally блока try... Перехватить... Finally , в выражении переменной цикла управления цикла For или For 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

Большинство асинхронных методов возвращает Task или Task<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 повторно создает OperationCanceledException.If 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.

Примеры обработки ошибок в асинхронных методах см. в разделе try... Перехватить... Оператор finally.For examples of error handling in async methods, see Try...Catch...Finally Statement.

ПримерExample

В следующем примере Windows Forms демонстрируется использование Await в асинхронном методе WaitAsynchronouslyAsync.The 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 выполняется синхронно, несмотря на использование модификатора Async в его определении и вызов Thread.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