并行执行异步方法的最佳实践

打印 上一主题 下一主题

主题 878|帖子 878|积分 2634

前言

最近写了三篇关于并行异步的博客,因为我走了很多弯路。
并行执行异步方法并接收返回值这个问题,stackoverflow上讨论好几年,.NET 6实现了Parallel.ForeachAsync。https://stackoverflow.com/questions/15136542/parallel-foreach-with-asynchronous-lambda
.NET 6 中的 API Parallel.ForEachAsync 在官方的博客中一直被忽略,但是我觉得这个 API 非常的实用!(这句话参考了博客:https://blog.csdn.net/sD7O95O/article/details/117914853)
要求


  • 必须接收处理返回值
示例1


示例2


代码说明


  • 上述代码我觉得非常优雅,java是无法优雅地写出来的,会很难阅读和维护。java19也许可以。
  • 使用场景:普通的增删改查功能估计是用不到,但我用到了。
  • 上述代码的并行度,可以根据es集群的性能和吞吐量以及具体需求,进行合理的调整。
可以复制的代码

上述代码是图片不方便复制,可以复制的代码在 探索:优雅地实现异步方法的并行执行 文章的最后。
简单的示例Demo代码
  1. private async void button4_Click(object sender, EventArgs e)
  2. {
  3.     await Task.Run(async () =>
  4.     {
  5.         Log($"==== 并行异步 开始,线程ID={Thread.CurrentThread.ManagedThreadId} ========================");
  6.         Stopwatch sw = Stopwatch.StartNew();
  7.         HttpClient httpClient = HttpClientFactory.GetClient();
  8.         var tasks = new Dictionary<string, Task<Dictionary<int, int>>>();
  9.         ConcurrentQueue<string> strs = new ConcurrentQueue<string>();
  10.         await Parallel.ForEachAsync(Enumerable.Range(0, m), new ParallelOptions() { MaxDegreeOfParallelism = 100 }, async (i, c) =>
  11.         {
  12.             int sum = 0;
  13.             await Parallel.ForEachAsync(Enumerable.Range(0, n), new ParallelOptions() { MaxDegreeOfParallelism = 30 }, async (j, c) =>
  14.             {
  15.                 Dictionary<int, int> dict = await RequestAsync(_url, i);
  16.                 if (dict.ContainsKey(j))
  17.                 {
  18.                     int num = dict[j];
  19.                     Interlocked.Exchange(ref sum, sum + num);
  20.                     strs.Enqueue($"{num}");
  21.                 }
  22.             });
  23.             Log($"输出:sum={sum}");
  24.         });
  25.         Log($"输出:{string.Join(",", strs.ToArray())}");
  26.         sw.Stop();
  27.         Log($"==== 结束,线程ID={Thread.CurrentThread.ManagedThreadId},耗时:{sw.Elapsed.TotalSeconds:0.000}秒 ========================");
  28.     });
  29. }
复制代码
上述代码说明

代码中 Parallel.ForEachAsync(Enumerable.Range(0, m),... 代替了for循环。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

美丽的神话

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表