等待的行为看起来同步在一个循环? [英] Await behavior looks synchronous in a loop?

查看:267
本文介绍了等待的行为看起来同步在一个循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请注意:这基本上只是说明我是混淆了异步。也许这可以帮助其他人感到困惑。

Note:this basically just illustrates me being confused about async. Maybe it can help other confused people.

我在做一些HttpClient的异步等待在一个循环的要求,我注意到,请求似乎是顺序执行的(它等待的结果开始下一次迭代之前)。

I was doing some HttpClient async await requests in a loop, and I noticed that the requests seemed to be done sequentially (it waited for the result before starting next iteration).

所以我试图用一个测试循环中,而不是Web请求等待Task.Delay。

So I tried a test using await Task.Delay in a loop instead of web requests.

也许我已经失去了情节,但我本来以为在一个循环,等待可能会导致,而其结果是期待已久的开始循环的下一次迭代。相反,它似乎一切都依次执行:

Maybe I've lost the plot, but I would have thought that await in a loop could result in the next iteration of the loop starting while the result is awaited. Instead it seems that everything executes in sequence:

        int _iterations = 1000;

        int _count= 0;

        Stopwatch   _stopwatch = new Stopwatch();
                    _stopwatch.Start();                      

        for (int i=0; i<_iterations; i++)
        {
                Console.WriteLine("Elapsed: {0}. Calls count: {1}.", _stopwatch.Elapsed, ++_count);

                await Task.Delay(5000);

                Console.WriteLine("Calls count again: {0}", _count);
        }

其结果是:

Elapsed: 00:00:00.0000059. Calls count: 1.
Calls count again: 1
Elapsed: 00:00:05.0022733. Calls count: 2.
Calls count again: 2
Elapsed: 00:00:10.0100470. Calls count: 3.
Calls count again: 3
Elapsed: 00:00:15.0182479. Calls count: 4.

是的,我可以离开了的await和返回任务添加到一些数组,并使用Task.WhenAll。不过,我很惊讶,伺机在我的循环阻塞,而且它所有的顺序执行。这是正常的吗?

Yes, I could leave out the await and add the returned Tasks to some array and use Task.WhenAll. But I am surprised that await is blocking in my loop, and that it all executes sequentially. Is this normal?

编辑:所以在最后:我有点糊涂了那里。控制返回到在等待外循环。这是有意义的,因为其模拟同步类推,但当然不会阻塞线程。

So in conclusion: I got a bit confused there. Control is returned to outside the loop at the await. This makes sense because it mimics the synchronous analogy, but of course does not block the thread.

推荐答案

这是整点等待:是,code的外观和行为几乎一样正常同步code,但它不是阻塞线程。如果你想在同一时间开始大量的就业机会,然后等待他们全部完成,你必须移动等待的循环之后。

That's the whole point of await: that the code looks and behaves almost the same as normal synchronous code, except it's not blocking a thread. If you want to start many jobs at the same time, and then wait for them all to finish, you have to move the await after the loop.

喜欢的东西(假设下划线的标识符字段):

Something like (assuming underscored identifiers are fields):

async Task PerformIteration()
{
    Console.WriteLine(
        "Elapsed: {0}. Calls count: {1}.", _stopwatch.Elapsed, ++_count);

    await Task.Delay(5000);

    Console.WriteLine("Calls count again: {0}", _count);
}

...

var tasks = new List<Task>();

for (int i=0; i<_iterations; i++)
{
    tasks.Add(PerformIteration());
}

await Task.WhenAll(tasks);

如果你想要做的事每次迭代完成后右侧单独的方法是必要的(在你的情况下,第二的WriteLine())。如果你不需要,你只需要添加 Task.Delay的结果()直接任务收集秒。

The separate method is necessary if you want to do something right after each iteration completes (in your case, the second WriteLine()). If you don't need that, you could just add the result of Task.Delay() directly to the collection of Tasks.

这篇关于等待的行为看起来同步在一个循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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