C# 无法等待异步lambda

C# 无法等待异步lambda,c#,task-parallel-library,async-await,async-ctp,C#,Task Parallel Library,Async Await,Async Ctp,想想这个, Task task = new Task (async () =>{ await TaskEx.Delay(1000); }); task.Start(); task.Wait(); call task.Wait()不会等待任务完成,下一行将立即执行,但是如果我将异步lambda表达式包装到方法调用中,代码将按预期工作 private static async Task AwaitableMethod() { await TaskEx.Delay(1000)

想想这个,

Task task = new Task (async () =>{
    await TaskEx.Delay(1000);
});
task.Start();
task.Wait(); 
call task.Wait()不会等待任务完成,下一行将立即执行,但是如果我将异步lambda表达式包装到方法调用中,代码将按预期工作

private static async Task AwaitableMethod()
{
    await TaskEx.Delay(1000);    
}
然后(根据svick的评论更新)


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

Task<Task> task = new Task<Task>(async () => {
    await Task.Delay(1000);
});
task.Start();
task.Wait(); 
task.Result.Wait();
Task Task=新任务(异步()=>{
等待任务。延迟(1000);
});
task.Start();
task.Wait();
task.Result.Wait();
您可以避免构建新任务,只需处理一个任务,而不是两个:

Func<Task> task = async () => {
    await TaskEx.Delay(1000);
};
task().Wait();
Func任务=async()=>{
等待TaskEx.延迟(1000);
};
task().Wait();

您需要使用
TaskEx.RunEx

通过在内部等待内部任务,它本机支持在
TaskPool
上运行
async
方法。否则,您将遇到您所面临的问题,其中只等待外部任务,这显然会立即完成,留下一个仍然需要等待的任务,或者在您的情况下(甚至更糟),留下一个无法等待的空lambda

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

当前代码(固定):


AwaitableMethod
中,您实际上是在返回并调用从.Delay()方法返回的任务上的Wait(我假设它返回一个
task
)。在异步lambda中,您正在调用
任务任务上的Wait
。但是,我仍然没有解释。您应该非常小心地将
Wait
Wait()
混合使用。在许多情况下,这可能会导致死锁。@svick发现将
Wait
Wait()
混合在一起有一个很好的解释,但是代码TaskEx.Run不起作用,仍然存在同样的问题。啊,对不起!我正在使用.NET4.5。。。我想写TaskEx.RunEx。将其签名与TaskEx.Run进行比较-您将了解为什么它专门用于运行异步方法。我强烈建议阅读和。如果第一次等待是在大量处理之后,您可能仍然需要双重任务。除了
task.Result.Wait()
之外,您还可以执行
task.Unwrap().Wait()
(或
Unwrap()
非无效方法)。新的
任务。Run
方法会自动展开,因此您只需等待预期的任务。作为初学者,我觉得他们可以用
async
关键字做得更好;这非常令人困惑。是否可以在不启动嵌套任务的情况下启动容器任务?潜在陷阱链接已断开,现在已被禁用
Func<Task> task = async () => {
    await TaskEx.Delay(1000);
};
task().Wait();
Task task = new Task<Task>(async () =>{
    await TaskEx.Delay(1000);
});

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

await task;