Оператор 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
выражение не может возникать в выражении запроса или блоке Finally
Catch
try... Поймать... Наконец, оператор в выражении переменной элемента управления циклом или For Each
For
цикле или в тексте инструкции 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