C# 不能等待异步 lambda

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13046096/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 01:27:04  来源:igfitidea点击:

can not await async lambda

c#task-parallel-libraryasync-awaitasync-ctp

提问by kennyzx

Consider this,

考虑到这一点,

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

The call task.Wait() does not wait for the task completion and the next line is executed immediately, but if I wrap the async lambda expression into a method call, the code works as expected.

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

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

then (updated according comment from svick)

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

await AwaitableMethod(); 

采纳答案by Joe Daley

In your lambda example, when you call task.Wait(), you are waiting on the new Task that you constructed, not the delay Task that it returns. To get your desired delay, you would need to also wait on the resulting Task:

在您的 lambda 示例中,当您调用 时task.Wait(),您正在等待您构造的新任务,而不是它返回的延迟任务。要获得所需的延迟,您还需要等待生成的任务:

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

You could avoid constructing a new Task, and just have one Task to deal with instead of two:

您可以避免构建一个新任务,而只需处理一个而不是两个任务:

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

回答by Lawrence Wagerfield

You need to use TaskEx.RunEx.

您需要使用TaskEx.RunEx.

It natively supports running asyncmethods on the TaskPoolby awaiting the inner task internally. Otherwise you'll run into the issue you're facing, where only the outer task is awaited, which obviously completes immediately, leaving either a task which still needs awaiting, or in your case (and even worse) a void lambda which cannot be awaited.

它通过在内部等待内部任务来原生地支持在async上运行方法TaskPool。否则你会遇到你面临的问题,只等待外部任务,这显然会立即完成,留下一个仍然需要等待的任务,或者在你的情况下(甚至更糟)一个无效的 lambda 不能等待。

Alternatively, you can await the task twice, providing you construct your outer task correctly (which currently you are not).

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

Current code (fixed):

当前代码(固定):

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

task.Start();
var innerTask = await task;
await innerTask;

Using TaskEx.RunEx:

使用 TaskEx.RunEx:

Task task = TaskEx.RunEx(async () =>{ // Framework awaits your lambda internally.
    await TaskEx.Delay(1000);
});

await task;