Поделиться через


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

Оператор применяется Await к операнду в асинхронном методе или лямбда-выражении, чтобы приостановить выполнение метода до завершения ожидаемой задачи. Задача представляет выполняющуюся работу.

Метод, в котором Await используется, должен иметь модификатор Async . Такой метод, определенный с помощью Async модификатора, и обычно содержащий одно или несколько Await выражений, называется асинхронным методом.

Замечание

Ключевые слова Async и Await были введены в Visual Studio 2012. Общие сведения о асинхронном программировании см. в статье "Асинхронное программирование" и "Ожидание".

Как правило, задача, к которой применяется 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

Это важно

Полный пример см. в пошаговом руководстве. Доступ к Интернету с помощью асинхронного и await. Пример можно скачать из браузера примеров .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. Термин Await служит ключевым словом только в этом контексте. В другом месте он интерпретируется как идентификатор. Async В методе или лямбда-выражении Await выражение не может возникать в выражении запроса или блоке FinallyCatchtry... Ловить... Наконец, оператор в выражении переменной элемента управления циклом или ForFor Each цикле или в тексте инструкции SyncLock.

Исключения

Большинство асинхронных методов возвращают или TaskTask<TResult>. Свойства возвращаемой задачи содержат сведения о его состоянии и журнале, например о том, завершена ли задача, асинхронный метод вызвал исключение или был отменен, а также о том, что такое окончательный результат. Оператор Await обращается к этим свойствам.

Если вы ожидаете возвращающий задачу асинхронный метод, вызывающий исключение, Await оператор перезаронит исключение.

Если вы ожидаете возвращающий задачу асинхронный метод, который отменен, Await оператор перезаронит объект OperationCanceledException.

Одна задача, которая находится в состоянии сбоя, может отражать несколько исключений. Например, задача может быть результатом вызова метода Task.WhenAll. При ожидании такой задачи операция ожидания повторно выполняется только один из исключений. Однако вы не можете предсказать, какие из исключений перезаписывается.

Примеры обработки ошибок в асинхронных методах см. в статье "Попробуйте... Ловить... Наконец, оператор.

Пример

В следующем примере 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

См. также