简体   繁体   English

如何在没有停止的情况下在另一个异步方法中创建调用异步方法

[英]How can I create call an async method inside another async method without it stalling

I need to call multiple async methods and inside of them, call another async method aswell. 我需要调用多个异步方法,并在其中调用另一个异步方法。 Let me demonstrate 让我来证明一下

private async void button1_Click(object sender, EventArgs e)
{
    for(int i = 0; i< 100; i++)
    {
        await Method1();
    }
}

public async Task Method1()
{
    await Task.Delay(3*1000);
    await Method2();
}

public async Task Method2()
{
    await Task.Delay(10*1000);
}

My problem is, the for statement only activates the iterations after the wait on Method2 starts and what I want is to create the 100 Task all at once. 我的问题是,for语句只在Method2启动等待后激活迭代,我想要的是一次创建100任务。 Everything else will be done asynchronously. 其他一切都将异步完成。

I think you are confused as to what "await" means. 我觉得你对“等待”意味着什么感到困惑。 "await" means "start processing this thing asynchronously, and while that is ticking away, go back to the windows message loop and keep on processing messages so that the UI keeps on re-drawing. When the asynchronous task is done, pick up the code where I awaited". “await”意味着“开始异步处理这个东西,当它正在消失时,回到windows消息循环并继续处理消息,以便UI继续重新绘制。当异步任务完成时,拿起我等待的代码“。

So when you await in a loop like that, you are saying: 所以当你在这样的循环中await时,你会说:

  • Start the first asynchronous job... 启动第一个异步作业......
  • and while it is running, keep processing the message loop. 当它正在运行时,继续处理消息循环。
  • When the first asynchronous job is done... 第一个异步作业完成后......
  • pick up in the loop where we awaited. 在我们期待的循环中接受。 We go around the loop and... 我们围绕循环......
  • Start the second asynchronous job... 启动第二个异步作业......

If that's not what you want then don't await the task . 如果这不是你想要的,那么就不要等待任务了 If you want to start a hundred tasks that run concurrently then start a hundred tasks and don't await any of them . 如果要启动一百个并发运行的任务,则启动一百个任务,不要等待其中任何一个任务 Why is there any await in the click handler? 为什么在点击处理程序中有任何等待?

Rather than await -ing each tasks as you create it in the for loop, you just want to start all of the tasks. 而不是在for循环中创建它时await每个任务,您只需要启动所有任务。 You don't want to delay the scheduling of the next task until the previous finished, so just don't await : 您不希望延迟下一个任务的调度,直到上一个完成,所以只是不要await

private void button1_Click(object sender, EventArgs e)
{
    for(int i = 0; i< 100; i++)
    {
        var task = Method1();
    }
}

Done. 完成。

If it's important that you do something after all of the tasks finish, while still doing all of them in parallel, then you can rely on Task.WhenAll to generate a task that will be completed when all of the other tasks are done: 如果在完成所有任务后执行某些操作非常重要,同时仍然并行完成所有任务,则可以依赖Task.WhenAll生成将在完成所有其他任务时完成的任务:

private async void button1_Click(object sender, EventArgs e)
{
    var tasks = new List<Task>();
    for(int i = 0; i< 100; i++)
    {
        tasks.Add(Method1());
    }
    await Task.WhenAll(tasks);
    textbox1.Text = "Done!"; //or whatever you want to do when they're all done
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM