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


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

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

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

Примечание.

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

Как правило, задача, к которой применяется Await оператор, является возвращаемым значением из вызова метода, реализующего асинхронный шаблон на основе задач, то есть или 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. Пример можно скачать из браузера примеров .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... Поймать... Наконец, оператор в выражении переменной элемента управления циклом или For EachFor цикле или в тексте инструкции SyncLock.

Исключения

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

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

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

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

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

Пример

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

См. также