Не может ждать асинхронной лямбда
Рассмотрим это,
Task task = new Task (async () =>{
await TaskEx.Delay(1000);
});
task.Start();
task.Wait();
Задача вызова .Wait() не ждет завершения задачи, и следующая строка выполняется немедленно, но если я обернуваю выражение асинхронного лямбда в вызов метода, код работает как ожидалось.
private static async Task AwaitableMethod()
{
await TaskEx.Delay(1000);
}
затем (обновляется согласно комментарию от svick)
await AwaitableMethod();
Ответы
Ответ 1
В вашем примере lambda, когда вы вызываете task.Wait()
, вы ожидаете новой задачи, которую вы создали, а не Задержки, которые она возвращает. Чтобы получить желаемую задержку, вам также нужно будет ждать итоговую задачу:
Task<Task> task = new Task<Task>(async () => {
await Task.Delay(1000);
});
task.Start();
task.Wait();
task.Result.Wait();
Вы можете избежать создания новой задачи и просто иметь одну задачу для работы вместо двух:
Func<Task> task = async () => {
await TaskEx.Delay(1000);
};
task().Wait();
Ответ 2
Вам нужно использовать TaskEx.RunEx
.
Он поддерживает поддерживающие методы async
на TaskPool
, ожидая внутренней внутренней задачи. В противном случае вы столкнетесь с проблемой, с которой вы столкнулись, где ожидает только внешняя задача, которая, очевидно, завершается немедленно, оставляя либо задачу, которая все еще нуждается в ожидании, либо в вашем случае (и еще хуже) недействительной лямбдой, которая не может быть ожидается.
В качестве альтернативы вы можете дважды подождать задания, чтобы вы правильно построили внешнюю задачу (в настоящее время вы не являетесь).
Текущий код (исправлено):
Task task = new Task<Task>(async () =>{
await TaskEx.Delay(1000);
});
task.Start();
var innerTask = await task;
await innerTask;
Использование TaskEx.RunEx:
Task task = TaskEx.RunEx(async () =>{ // Framework awaits your lambda internally.
await TaskEx.Delay(1000);
});
await task;