【问题标题】:Why is this async for loop that slow?为什么这个异步 for 循环那么慢?
【发布时间】:2012-10-18 16:09:53
【问题描述】:

我有以下 for 循环:

System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();

for (int i = 0; i < packets2.Count; i++)
{                       
    dosimulationasync(packets2[i]);                        
}

stopwatch.Stop();                    
logit("Time: " + stopwatch.ElapsedMilliseconds);

dosimulationasync 是这样的:

private async Task dosimulationasync(SimulationPoint mypoint)
{
    await TaskEx.Run(() =>
    {
        for (int i = 0; i < allobjects.Count; i++)
        {
            if (allobjects[i].ID == mypoint.ID)
            {
                allobjects[i].setvalue(mypoint);
                break;
            }
        }
    });
}

问题是第一个 for 循环,使用 stopwatch 捕获,它必须处理的值越多,它就会变得非常慢(比如 13 个值已经花费了大约时间:300 毫秒)。我认为通过异步调用 dosimulationasync 方法,第一个 for 循环将立即继续。

我无法解释为什么它变得那么慢,即使dosimulationasync 例程很慢,它也不应该影响第一个 for 循环,对吧?

我做错了什么?如何“发送”dosimulationasync

【问题讨论】:

  • 您应该考虑使用像 Visual Studio Express 或 SharpDevelop 这样的 IDE;这些 IDE 将为您正确格式化您的代码。将缩进和大括号放在错误的位置会使您的代码难以阅读和理解。
  • 如果您使用的是TaskEx.Run,​​这表明您仍在使用CTP...您能否在已发布版本上使用一个简短但完整的程序来重现这一点.NET 4.5 的?
  • 我也会尝试Parallel.For(0, packets2.Count, i =&gt; { dosimulationasync(packets2[i]); }); 看看有什么不同
  • @OndraMorský await 并不意味着它将停止,这意味着它将连接方法的其余部分作为延续。也就是说,由于 OP 从不等待从 dosimulationasync 返回的任务,他不妨删除所有对 async/await 的引用;它不会以任何功能方式更改代码。
  • 这是您的实际代码吗?你必须小心细粒度的并行性;如果您只是进行快速查找和设置,您可能应该对它们进行批处理,否则Task.Run 的开销会影响您的时间。

标签: c# loops asynchronous for-loop


【解决方案1】:

我认为在你的情况下,异步/等待不会帮助你。 并行方法是dosimulationasync,但其中没有什么可以并行处理。 我将完全删除 async/await 并在您的主要方法中使用 Parallel.For:

Parallel.For(0, packets2.Count, (i) =>
{                       
    dosimulationasync(packets2[i]);                        
});

但请确保您可以从数据包2中并行读取

【讨论】:

  • dosimulationasync 只是创建任务并安排它们,根本不会花费很长时间(因为代码实际上并没有等待这些任务)。任务的调度不需要并行,也不应该花费很长时间。
  • 我误解了这个问题。我以为他想衡量真正的工作。我的错。
  • 非常感谢各位帮手!奇怪的是,删除所有异步任务 - TaskEx.Run 东西并添加 Parallel.For() => .. 东西会导致更快的处理!并不是说我确实理解为什么 async Task - TaskEx.Run 比简单的 void () 慢...,但实际上我现在在 packet2-list 中的 13 个元素上运行 50 毫秒(与之前的 300 毫秒相比)。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-08
  • 2013-03-17
  • 2021-10-16
  • 1970-01-01
  • 2017-11-09
相关资源
最近更新 更多