Console.WriteLine(message);
string message1 = await DoWorkAsync().ConfigureAwait(false);
Console.WriteLine(message1);
В исходном блоке кода применяется класс SynchronizationContext
ConfigureAwait(true). Во втором примере текущий контекст и планировщик игнорируются.Согласно рекомендациям команды создателей .NET Core при разработке прикладного кода (Windows Forms, WPF и т.д.) следует полагаться на стандартное поведение, а в случае написания неприкладного кода (скажем, библиотеки) использовать вызов ConfigureAwait(false)
SynchronizationContext не создается; таким образом, вызов ConfigureAwait(false) не дает преимущества при работе с другими инфраструктурами. Соглашения об именовании асинхронных методов
Конечно же, вы заметили, что мы изменили имя метода с DoWork()
DoWorkAsync(), но по какой причине? Давайте предположим, что новая версия метода по-прежнему называется DoWork(), но вызывающий код реализован так:// Отсутствует ключевое слово await!
string message = DoWork();
Обратите внимание, что мы действительно пометили метод ключевым словом async
DoWork(). Здесь мы получим ошибки на этапе компиляции, потому что возвращаемым значением DoWork() является объект Task, который мы пытаемся напрямую присвоить переменной типа string. Вспомните, что ключевое слово await отвечает за извлечение внутреннего возвращаемого значения, которое содержится в объекте Task. Поскольку await отсутствует, возникает несоответствие типов.На заметку!
Метод, поддерживающийawait — это просто метод, который возвращает Task или Task.С учетом того, что методы, которые возвращают объекты Task
async и await, в Microsoft рекомендуют (в качестве установившейся практики) снабжать имя любого метода, возвращающего Task, суффиксом Async. В таком случае разработчики, которым известно данное соглашение об именовании, получают визуальное напоминание о том, что ключевое слово await является обязательным, если они намерены вызывать метод внутри асинхронного контекста.На заметку!
Обработчики событий для элементов управления графического пользовательского интерфейса (вроде обработчика событияClick кнопки), а также методы действий внутри приложений в стиле MVC, к которым применяются ключевые слова async и await, не следуют указанному соглашению об именовании.Асинхронные методы, возвращающие void
В настоящий момент наш метод DoWorkAsync()
Task, содержащий "реальные данные" для вызывающего кода, которые будут получены прозрачным образом через ключевое слово await. Однако что если требуется построить асинхронный метод, возвращающий void? Реализация зависит о того, нуждается метод в применении await или нет (как в сценариях "запустил и забыл").Асинхронные методы, возвращающие void и поддерживающие await
Если асинхронный метод должен поддерживать await
Task и опустите любые операторы return, например:static async Task MethodReturningTaskOfVoidAsync()
{
await Task.Run(() => { /* Выполнить какую-то работу... */
Thread.Sleep(4_000);
});
Console.WriteLine("Void method completed");
// Метод завершен
}
Затем в коде, вызывающем этот метод, примените ключевое слово await
MethodReturningVoidAsync();
Console.WriteLine("Void method complete");
Асинхронные методы, возвращающие void и работающие в стиле "запустил и забыл"
Если метод должен быть асинхронным, но не обязан поддерживать await
async и сделайте возвращаемым типом void, а не Task. Методы такого рода обычно используются для задач вроде ведения журнала, когда нежелательно, чтобы запись в журнал приводила к задержке выполнения остального кода.static async void MethodReturningVoidAsync()
{