it-swarm.com.ru

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

Учти это,

Task task = new Task (async () =>{
    await TaskEx.Delay(1000);
});
task.Start();
task.Wait(); 

Вызов task.Wait () не ожидает завершения задачи, и следующая строка выполняется немедленно, но если я заключу асинхронное лямбда-выражение в вызов метода, код будет работать, как и ожидалось.

private static async Task AwaitableMethod()
{
    await TaskEx.Delay(1000);    
}

затем (обновляется в соответствии с комментариями от svick)

await AwaitableMethod(); 
60
kennyzx

В вашем лямбда-примере, когда вы вызываете 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();
82
Joe Daley

Вам нужно использовать 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;
6
Lawrence Wagerfield