.NET 8.0预览版中Parallel.ForEach与Parallel.ForEachAsync哪个效率更高?
在.NET 8.0预览版中,Parallel.ForEach与Parallel.ForEachAsync的效率对比
针对你处理200条HTTP Rest调用的场景,直接给出结论:Parallel.ForEachAsync的效率远高于Parallel.ForEach,结合你的代码示例具体分析如下:
两种实现的核心差异与问题
代码示例1的缺陷
你用Parallel.ForEach启动异步任务再通过Task.WhenAll等待完成,这种做法存在两个关键问题:
- 线程资源浪费:
Parallel.ForEach是同步并行循环,会占用线程池线程执行循环体,但你的循环体仅做“启动HTTP异步请求”这一极轻量操作,请求启动后线程就会被释放,相当于用线程池线程做无意义的空转,还会额外增加线程调度开销。 - 线程安全隐患:
List<Task>的Add方法并非线程安全,多个线程同时调用tasks.Add(movieFromTmdb)会导致集合内部结构损坏,触发不可预料的错误。
代码示例2的优势
Parallel.ForEachAsync是.NET专为异步并行场景设计的API,完美适配你的IO密集型任务:
- 高效线程复用:在
await _tmdbClient.GetMovieAsync时,当前线程会被释放回线程池处理其他工作,等HTTP请求完成后再回调执行后续逻辑,不会占用线程资源等待IO操作。 - 内置并发控制:默认会根据系统资源合理控制并发度(也可通过
ParallelOptions手动配置),避免一次性发起过多HTTP请求导致服务端限流或本地资源耗尽。 - 线程安全的结果收集:
ConcurrentBag天然支持多线程安全写入,不存在集合损坏的风险。
.NET 8的额外优化
.NET 8对Parallel.ForEachAsync做了针对性调度优化,在处理批量异步IO操作时,相比旧版本以及错误使用Parallel.ForEach的方式,性能提升更显著。
内容的提问来源于stack exchange,提问作者Zoinky
相关产品推荐
相关产品推荐

