嵌套异步等待不等待

Ric*_*olo 4 c# asynchronous task async-await

我想我错过了解async awaitc#中的行为.

我有两个返回Task定义的方法

public async Task Name()
{
await AsyncOperation() 
}
Run Code Online (Sandbox Code Playgroud)

想象一下,AsyncOperation()像一个PostAsyncHttpClient.

现在我用其他方法调用它们

public asyn Task Method()
{
await Name1(() => { "bla bla"});
await Name2();
Console.WriteLine("Continue");
}
Run Code Online (Sandbox Code Playgroud)

这对我来说是预期的.等待,直到Name1()Name2()完成,然后继续.

现在我需要窝Name1()Name2().实际上Name1()是一个请求等待窗口,它接收一个慢速操作的lambda参数,而Name2()文件的下载速度很慢.我希望在下载文件时出现Plese Wait窗口.

所以我尝试这样的事情:

public asyn Task Method()
{
    await Name1( async ()=>
    {
        await Name2();
    }
    Console.WriteLine("Continue");
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,执行不会等待untile Name2()完成.为什么会发生这种情况并且await不等待?

更新

这是请等待的方法背后的逻辑.它显示使用Mahapps Dialogs的Please Wait消息,执行lambda 收到的代码,然后关闭please wait消息.

public static async Task Name1(Action longOperation)
{
    _progressController = await _metroWindow.ShowProgressAsync("Please wait...");            
    await Task.Run(() => longOperation());
    await _progressController.CloseAsync();
}
Run Code Online (Sandbox Code Playgroud)

dji*_*kay 5

Name1方法接受委托并返回委托返回的类型Task<T>where T.在您的情况下,委托返回Task,因此我们得到Task<Task>结果.使用await等待仅完成外部任务(立即返回内部任务),然后忽略内部任务.

你可以通过在lambda函数中删除async和await来解决这个问题.

另外,看看C#中的Asynchronous Gotchas.

  • @JohnathonSullinger,如果`longOperation`已经是*async*(返回一个`Task`),你很少需要用`Task.Run`包装它.只有在"longOperation"开头有一块阻塞或CPU密集型代码,或者如果你想在没有同步的情况下执行它,它才有意义.上下文.如果你确实包装它,`await Task.Run(()=> longOperation())`就足够了(不需要`async` lambda). (3认同)