【发布时间】:2019-07-17 23:19:56
【问题描述】:
我正在创建一个 .net 核心应用程序,我需要在其中调用 async 方法来处理大量对象。我们在Parallel.ForEach 中完成了这项工作,因此我们可以利用并行性更快地完成工作。
服务方法是async 方法,我们无法更改。我的问题是使用 TPL Parallel 时调用此方法的正确方法是什么。
这是一个简化的代码 sn-p(我传递迭代 # 而不是用于演示目的的对象),以及我们的观察结果:
CallSendAsync 方法在内部向 API 发出 HTTP 请求(使用 HttpClient)。
private void ParallelFor()
{
Parallel.For(0, 100000, i =>
{
CallSendAsync(i).GetAwaiter().GetResult();
});
}
我对上述代码的问题是,它使用了GetAwaiter,这使得async 方法同步。然而,上面的实现非常快。它似乎也更有效地管理系统资源。
另一方面,我有这个:
private void ParallelForWithAsync()
{
Parallel.For(0, 100000, async i =>
{
await CallSendAsync(i);
});
}
此代码有一个async/await。但是它变得非常慢,性能显着下降。它打开了大量的出站端口,最终导致 HTTP 请求出错。
第三次我也试过这个:
private void TaskWaitAll()
{
IEnumerable<int> arr = Enumerable.Range(1, 100000);
Task.WhenAll(arr.Select(CallSendAsync)).GetAwaiter().GetResult();
}
这也有与第二个 sn-p 相似的结果。
【问题讨论】:
标签: c# async-await task-parallel-library parallel.foreach