嵌套异步等待不等待 [英] Nested Async Await Does not Wait

查看:116
本文介绍了嵌套异步等待不等待的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我误解了c#中async await的行为.

我有两个方法返回定义为

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

Task

public async Task Name()
{
await AsyncOperation() 
}

想象AsyncOperation()就像HttpClientPostAsync.

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

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

这按我的预期工作.等待直到Name1()Name2()完成,然后继续.

现在我需要嵌套Name1()Name2().实际上,Name1()是一个请稍候"窗口,它会将lambda参数作为慢速操作接收,而Name2()是文件的慢速下载.我希望在下载文件时出现请等待"窗口.

所以我尝试这样的事情:

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

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

更新

这是请稍候的方法背后的逻辑.它使用 Mahapps对话框显示请稍等"消息,执行lambda接收的代码,然后关闭请稍候消息.

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

解决方案

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

您可以通过在lambda函数中删除异步并等待来解决此问题.

此外,请查看 C#中的异步陷阱.

I think I missunderstanding the behaviour of async await in c#.

I have two methods that return a Task defined like

public async Task Name()
{
await AsyncOperation() 
}

Imagine AsyncOperation() like an PostAsync of HttpClient.

Now I call them inside some other methods

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

This works as expected to me. Waits until Name1() and Name2() finish and then continues.

Now I need to nest Name1() and Name2(). In fact Name1() is a Please Wait Window that recieve as lambda parameters a slow operation, while Name2() is a slow download of a file. I want the Plese Wait window appears while the file is downloaded.

So I try something like this:

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

In this case the execution doesnt wait untile Name2() finished. Why this happen and await doesnt wait?

Update

This is the logic behind the method of please wait. It shows a Please Wait message using Mahapps Dialogs, executes the code that recieves by the lambda, and then close the please wait message.

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

解决方案

The Name1 method takes a delegate and returns a Task<T> where T is the type returned by the delegate. In your case, the delegate returns Task, so we get Task<Task> as the result. Using await waits only for the completion of the outer task (which immediately returns the inner task) and the inner task is then ignored.

You can fix this by dropping the async and await in the lambda function.

Also, take a look at Asynchronous Gotchas in C#.

这篇关于嵌套异步等待不等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆