【发布时间】:2017-07-09 22:07:11
【问题描述】:
同步代码:
public static void ImportData()
{
for (var i = 0; i < 40000; i++)
{
DoSomething(i)
}
}
异步代码:
public static void ImportDataAsync()
{
for (int i = 0; i < 40000; i++)
{
await DoSomething(i)
}
}
为了清楚起见,这是我第一次尝试异步操作。
使用异步代码,我的软件真的很慢,如果我同步运行命令行应用程序的多个实例,速度会快 10 倍。
我的意思是,我不认为 DB 访问和
GetAsync 函数的 try/catch 块会在这两种方法之间造成这种差异,你怎么看?
编辑:我不知道如何改进这个问题,但我会尝试给出答案。
我要问的是“Parallel.Foreach”方法,我正在做的是认为“await”前缀会将当前线程设置为待机创建另一个线程并继续 for 循环,而不是等待什么did 是简单地离开该方法直到等待结果,然后他在 for 循环中的同一点返回并在他等待的地方恢复它。
我只是把事情弄糊涂了,特别是在控制台应用程序中,实际上我没有看到任何使用 await/async 的充分理由。
【问题讨论】:
-
如果没有可靠地重现问题的良好minimal reproducible example,就无法回答。但是,一些观察:“快速”版本似乎完成了“慢”版本工作的 1/5。这将导致 5 倍的差异。此外,“慢速”版本似乎允许多达 100 个并发操作,这可能会产生大量争用(除非两端都有 100 个 CPU 和非常快的网络)。除此之外,您正在使用“旋转等待”来实现该节流,这意味着您在等待时会 100% 占用一个 CPU 内核,这只会使其他一切变慢。
-
事实是,如果你的机器上只有两个 CPU 内核,而“慢”版本确实做了 5 倍的工作,并且大部分操作成本是本地计算,那么上述观察将完全解释 10 倍的不同。如果不是,那么...您仍然需要解决问题,以便它包含一个好的minimal reproducible example,以便任何人诊断您的问题。可以说,正确完成异步不会以任何明显的方式影响这种情况下的性能,当然不会有 10 倍的差异。
-
我们怎么知道你为什么做错了?也许只是因为你不是很好?也许你想问这是怎么回事?
-
我还在学习,我仍然对异步世界有点困惑,但是我相信使用异步代码的主要目标不是让事情变得更快,而是在以下情况下不阻塞 UI 线程做同步的东西。您可以同时运行数千个 Get 请求,最终,您会遇到一些限制(网络、服务器、线程池等等)。虽然您可能认为并行运行所有内容应该会使事情运行得更快,但实际上可能会产生相反的效果(想想管理所有任务所需的所有工作等......)。
标签: c# asynchronous httpclient