不能等待异步 lambda

考虑一下,

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

调用任务。Wait ()不会等待任务完成,下一行会立即执行,但是如果我将异步 lambda 表达式包装到方法调用中,代码会按预期工作。

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

然后(根据 Svick 的评论更新)

await AwaitableMethod();
91532 次浏览

在您的 lambda 示例中,当您调用 task.Wait()时,您正在等待您构造的新 Task,而不是它返回的延迟 Task。为了得到你想要的延迟,你还需要等待结果任务:

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

你需要使用 TaskEx.RunEx

通过在内部等待内部任务,它本身支持在 TaskPool上运行 async方法。否则你就会遇到你正面临的问题,那里只有外部任务在等待,而且显然是立即完成的,留下一个任务仍然需要等待,或者在你的情况下(甚至更糟)一个空的 lambda 不能被等待。

或者,您可以等待任务两次,前提是您正确地构造了外部任务(目前您还没有构造好)。

现行代码(固定) :

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;