4

我需要调用多个异步方法,并在其中调用另一个异步方法。让我演示一下

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);
}

我的问题是,for 语句仅在 Method2 的等待开始后激活迭代,而我想要的是一次创建 100 个任务。其他一切都将异步完成。

4

2 回答 2

8

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".

So when you await in a loop like that, you are saying:

  • 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?

于 2013-04-24T21:05:58.767 回答
3

而不是await在 for 循环中创建每个任务时对其进行 -ing,您只想启动所有任务。您不想将下一个任务的调度延迟到上一个任务完成之前,所以不要await

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

完毕。

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:

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
}
于 2013-04-24T21:05:28.593 回答