Подтвердить что ты не робот

Не может ждать асинхронной лямбда

Рассмотрим это,

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(); 
4b9b3361

Ответ 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;