Оператор await — асинхронное ожидание завершения задачи.
Оператор await
приостанавливает вычисление включающего асинхронного метода до завершения асинхронной операции, представленной его операндом. После завершения асинхронной операции оператор await
возвращает результат операции, если таковой имеется. Когда оператор await
применяется к операнду, который представляет уже завершенную операцию, он возвращает результат операции немедленно без приостановки включающего метода. Оператор await
не блокирует поток, который вычисляет асинхронный метод. Когда оператор await
приостанавливает включающий метод async, элемент управления возвращается вызывающему объекту метода.
В следующем примере метод HttpClient.GetByteArrayAsync возвращает экземпляр Task<byte[]>
, который представляет асинхронную операцию, создающую массив байтов после завершения. До завершения операции оператор await
приостанавливает метод DownloadDocsMainPageAsync
. Когда DownloadDocsMainPageAsync
приостанавливается, управление возвращается методу Main
, который является вызывающим объектом DownloadDocsMainPageAsync
. Метод Main
выполняется до тех пор, пока ему не потребуется результат асинхронной операции, выполняемой методом DownloadDocsMainPageAsync
. Когда GetByteArrayAsync получает все байты, вычисляется остальная часть метода DownloadDocsMainPageAsync
. После этого вычисляется остальная часть метода Main
.
using System;
using System.Net.Http;
using System.Threading.Tasks;
public class AwaitOperator
{
public static async Task Main()
{
Task<int> downloading = DownloadDocsMainPageAsync();
Console.WriteLine($"{nameof(Main)}: Launched downloading.");
int bytesLoaded = await downloading;
Console.WriteLine($"{nameof(Main)}: Downloaded {bytesLoaded} bytes.");
}
private static async Task<int> DownloadDocsMainPageAsync()
{
Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: About to start downloading.");
var client = new HttpClient();
byte[] content = await client.GetByteArrayAsync("https://learn.microsoft.com/en-us/");
Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: Finished downloading.");
return content.Length;
}
}
// Output similar to:
// DownloadDocsMainPageAsync: About to start downloading.
// Main: Launched downloading.
// DownloadDocsMainPageAsync: Finished downloading.
// Main: Downloaded 27700 bytes.
В предыдущем примере используется асинхронный Main
метод . Дополнительные сведения см. в описании оператора await в методе Main.
Примечание
Общие сведения об асинхронном программировании см. в разделе Асинхронное программирование с использованием ключевых слов async и await. Асинхронное программирование async
и await
следует асинхронной модели, основанной на задачах.
Оператор await
можно использовать только в методе, лямбда-выражении или в анонимном методе, изменяемом ключевым словом async. В асинхронном методе нельзя использовать оператор await
в теле синхронной функции, внутри блока инструкции lock и в ненадежном контексте.
Операнд оператора await
обычно имеет один из следующих типов .NET: Task, Task<TResult>, ValueTask или ValueTask<TResult>. Однако любое ожидаемое выражение может быть операндом оператора await
. Дополнительные сведения см. в разделе об ожидаемых выражениях в спецификации языка C#.
Тип выражения await t
является TResult
, если тип выражения t
является Task<TResult> или ValueTask<TResult>. Если тип t
является Task или ValueTask, тип await t
является void
. В обоих случаях, если t
вызывает исключение, await t
воспроизводит это исключение.
Асинхронные потоки и освобождаемые объекты
Вы можете использовать инструкцию await foreach
для работы с асинхронным потоком данных. Дополнительные сведения см. в foreach
разделе операторов статьи Операторы итерации .
Инструкция await using
используется для работы с асинхронно освобождаемым объектом, то есть с объектом типа, который реализует интерфейс IAsyncDisposable. Дополнительные сведения см. в разделе Использование асинхронных освобождаемых объектов статьи Реализация метода DisposeAsync.
Оператор await в методе Main
МетодMain
, который является точкой входа приложения, может возвращать Task
или Task<int>
, что позволяет ему быть асинхронным, чтобы можно было использовать await
оператор в его теле. В более ранних версиях C#, чтобы убедиться, что метод Main
ожидает завершения асинхронной операции, можно получить значение свойства Task<TResult>.Result экземпляра Task<TResult>, возвращаемого соответствующим асинхронным методом. Для асинхронных операций, которые не создают значение, можно вызвать метод Task.Wait. См. сведения о том, как выбрать версию языка в описании версий C#.
Спецификация языка C#
Дополнительные сведения см. в разделе об ожидаемых выражениях в спецификации языка C#.
См. также
- справочник по C#
- Операторы и выражения C#
- async
- Асинхронная модель программирования
- Асинхронное программирование
- Пошаговое руководство. Получение доступа к Интернету с помощью async и await
- Руководство. Создание и использование асинхронных потоков
- Блог .NET: Как async/await действительно работает в C #
.NET feedback
The .NET documentation is open source. Provide feedback here.
Обратная связь
Отправить и просмотреть отзыв по