Язык программирования C#9 и платформа .NET5
Асинхронные методы, возвращающие void и поддерживающие await
Если асинхронный метод должен поддерживать
, тогда используйте необобщенный классawaitи опустите любые операторыTask, например:returnstatic async Task MethodReturningTaskOfVoidAsync(){await Task.Run(() => { /* Выполнить какую-то работу... */Thread.Sleep(4_000);});Console.WriteLine("Void method completed");// Метод завершен}Затем в коде, вызывающем этот метод, примените ключевое слово
:awaitMethodReturningVoidAsync();Console.WriteLine("Void method complete");Асинхронные методы, возвращающие void и работающие в стиле "запустил и забыл"
Если метод должен быть асинхронным, но не обязан поддерживать
и применяться в сценариях "запустил и забыл", тогда добавьте ключевое словоawaitи сделайте возвращаемым типомasync, а неvoid. Методы такого рода обычно используются для задач вроде ведения журнала, когда нежелательно, чтобы запись в журнал приводила к задержке выполнения остального кода.Taskstatic async void MethodReturningVoidAsync(){await Task.Run(() => { /* Выполнить какую-то работу... */Thread.Sleep(4_000);});Console.WriteLine("Fire and forget void method completed");// Метод завершен}Затем в коде, вызывающем этот метод, ключевое слово
не используется:awaitMethodReturningVoidAsync();Console.WriteLine("Void method complete");Асинхронные методы с множеством контекстов await
Внутри реализации асинхронного метода разрешено иметь множество контекстов
. Следующий код является вполне допустимым:awaitstatic async Task MultipleAwaits(){await Task.Run(() => { Thread.Sleep(2_000); });Console.WriteLine("Done with first task!");// Первая задача завершена!await Task.Run(() => { Thread.Sleep(2_000); });Console.WriteLine("Done with second task!");// Вторая задача завершена!await Task.Run(() => { Thread.Sleep(2_000); });Console.WriteLine("Done with third task!");// Третья задача завершена!}Здесь каждая задача всего лишь приостанавливает текущий поток на некоторый период времени; тем не менее, посредством таких задач может быть представлена любая единица работы (обращение к веб-службе, чтение базы данных или что-нибудь еще). Еще один вариант предусматривает ожидание не каждой отдельной задачи, а всех их вместе. Это более вероятный сценарий, когда имеются три работы (скажем, проверка поступления сообщений электронной почты, обновление сервера, загрузка файлов), которые должны делаться в пакете, но могут выполняться параллельно. Ниже приведен модифицированный код, в котором используется метод
:Task.WhenAll()static async Task MultipleAwaits(){var task1 = Task.Run(() =>{Thread.Sleep(2_000);Console.WriteLine("Done with first task!");});var task2=Task.Run(() =>{Thread.Sleep(1_000);Console.WriteLine("Done with second task!");});var task3 = Task.Run(() =>{Thread.Sleep(1_000);Console.WriteLine("Done with third task!");});await Task.WhenAll(task1, task2, task3);}Запустив программу, вы увидите, что три задачи запускаются в порядке от наименьшего значения, указанного при вызове метода
:Sleep()Fun With Async ===>Done with work!Void method completedDone with second task!Done with third task!Done with first task!CompletedСуществует также метод
, возвращающий задачу, которая завершилась. Для демонстрации работыWhenAnу()измените последнюю строку методаWhenAny()следующим образом:MultipleAwaits()