gpt4 book ai didi

c# - 等待行为在循环中看起来是同步的?

转载 作者:行者123 更新时间:2023-11-30 19:41:40 26 4
gpt4 key购买 nike

注意:这基本上只是说明我对 async 感到困惑。也许它可以帮助其他困惑的人。

我在循环中执行一些 HttpClient async await 请求,我注意到请求似乎是按顺序完成的(它等待开始下一次迭代之前的结果)。

所以我尝试在循环中使用 await Task.Delay 代替网络请求进行测试。

也许我已经失去了情节,但我认为循环中的 await 可能会导致在等待结果时开始循环的下一次迭代。相反,似乎一切都按顺序执行:

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 添加到某个数组并使用 Task.WhenAll。但令我惊讶的是 await 在我的循环中阻塞了,而且它都是按顺序执行的。这正常吗?

编辑:总而言之:我在那里有点困惑。控制在 await 处返回到循环外。这是有道理的,因为它模仿了同步类比,但当然不会阻塞线程。

最佳答案

这就是 await 的全部要点:代码的外观和行为与普通同步代码几乎相同,只是它不阻塞线程。如果你想同时启动许多作业,然后等待它们全部完成,你必须将 await 移到循环之后。

类似于(假设带下划线的标识符是字段):

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() 的结果添加到 Task 的集合中。

关于c# - 等待行为在循环中看起来是同步的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19089811/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com