72

考虑到这一点,

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

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

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

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

await AwaitableMethod(); 
4

2 回答 2

94

在您的 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();
于 2012-10-24T10:00:10.553 回答
8

你需要使用TaskEx.RunEx.

它通过在内部等待内部任务来原生支持运行async方法。TaskPool否则你会遇到你面临的问题,只有外部任务在等待,显然会立即完成,留下一个仍然需要等待的任务,或者在你的情况下(甚至更糟)一个无效的 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;
于 2012-10-24T10:31:46.433 回答