Как ждать делегата async
В одном из видео MVA я увидел следующую конструкцию:
static void Main(string[] args)
{
Action testAction = async () =>
{
Console.WriteLine("In");
await Task.Delay(100);
Console.WriteLine("First delay");
await Task.Delay(100);
Console.WriteLine("Second delay");
};
testAction.Invoke();
}
Результатом выполнения будет:
In
Press any key to continue . . .
Он отлично компилируется, но прямо сейчас я не вижу способа подождать. Я мог бы поставить Thread.Sleep
или Console.ReadKey
после вызова, но это не то, что я хочу.
Итак, как этот делегат должен быть изменен, чтобы стать ожидаемым? (или, по крайней мере, как я могу отслеживать выполнение этого выполнения?)
Есть ли практическое использование таких делегатов?
Ответы
Ответ 1
Чтобы ожидание ожидалось, оно должно быть ожидаемым. Поскольку void
не так, вы не можете ждать ни одного делегата Action
.
Ожидается любой тип, реализующий метод GetAwaiter
, который возвращает тип, который реализует, например, INotifyCompletion
или ICriticalNotifyCompletion
, например Task
и Task<T>
.
Если вы хотите ждать делегата, используйте Func<Task>
, который эквивалентен именованному методу со следующей подписью:
public Task Func()
Итак, чтобы ждать, измените свой метод на:
static void Main(string[] args)
{
Func<Task> testFunc = async () =>
{
Console.WriteLine("In");
await Task.Delay(100);
Console.WriteLine("First delay");
await Task.Delay(100);
Console.WriteLine("Second delay");
};
}
И теперь вы можете ждать:
await testFunc();
Ответ 2
"Async void - только для обработчиков событий верхнего уровня",
http://channel9.msdn.com/Series/Three-Essential-Tips-for-Async/Tip-1-Async-void-is-for-top-level-event-handlers-only
Ответ 3
Недавно я обнаружил, что NUnit способен проверять await
async void
. Вот хорошее описание, как это работает: Как nunit успешно ждет завершения асинхронных методов?
Вы не будете использовать его в обычных задачах, но хорошо знать, что это возможно