C# 提供了几种不同的遍历方式,各有优缺点,今天我们来用真实代码和具体场景,一次讲清楚: Parallel.ForEach 和 Parallel.ForEachAsync List<T>.ForEach .NET 6 起还支持异步版本: await Parallel.ForEachAsync(myList, async (item, token) => { await ProcessAsync( 对比总结表 遍历方式 是否支持并发 是否支持异步 顺序是否保证 支持的集合类型 推荐使用场景 Parallel.ForEach ✅ ❌ ❌ 所有 IEnumerable 并行处理 CPU 密集型任务 Parallel.ForEachAsync 顺序异步执行,控制清晰 await foreach(异步流) ❌ ✅ ✅ 异步可枚举对象 异步流处理,如数据库流、消息流等 如果你任务之间没啥依赖,又想快, 并发用 Parallel.ForEach 或 Parallel.ForEachAsync
types = _container.ComponentRegistry.Registrations.Select(a => a.Activator.LimitType); await Parallel.ForEachAsync types = _container.ComponentRegistry.Registrations.Select(a => a.Activator.LimitType); await Parallel.ForEachAsync
多任务的异步 Parallel.ForEachAsync 在多任务中,以前只有一个 Parallel.ForEach 的方法,用来同步执行。 这回终于把异步方法 Parallel.ForEachAsync 加进来了,足以可见微软在异步方面的深化决心。 urls = new [] { "https://test1.com", "https://test2.com" }; var client = new HttpClient(); await Parallel.ForEachAsync
使用 Parallel.ForEachAsync 实现真正的异步并行 开发者通常使用 Parallel.ForEach,但它不支持 async/await。 相反,使用 Parallel.ForEachAsync: await Parallel.ForEachAsync(myCollection, async (item, token) => { await Parallel.ForEachAsync 实现了真正的异步并行。 TryAdd() 避免了不必要的字典查找。 ValueTask<T> 减少了内存分配。
使用 Parallel.ForEachAsync 实现真正的异步并行 开发者通常使用 Parallel.ForEach,但它不支持 async/await。 相反,使用 Parallel.ForEachAsync: await Parallel.ForEachAsync(myCollection, async (item, token) => { await • Parallel.ForEachAsync 实现了真正的异步并行。 • TryAdd() 避免了不必要的字典查找。 • ValueTask<T> 减少了内存分配。
TimeOnly timeOnlyFromDate = TimeOnly.FromDateTime(DateTime.Now); Console.WriteLine(timeOnlyFromDate); Parallel.ForEachAsync ProductInfoHeaderValue("DotNet", "6")); ParallelOptions options = new() { MaxDegreeOfParallelism = 3 }; await Parallel.ForEachAsync
a = 1; Thread.Sleep(200); } }); } int i = 0; await Parallel.ForEachAsync
限制并发:使用 Channel 或 Parallel.ForEachAsync 来进行可控的并行处理。 资源管理:妥善处置文件句柄或数据库连接等资源。 避免过载:不要获取或处理超出必要范围的数据。
性能优化技巧 为了在数据量大、操作复杂的情况下仍能保持高性能,可以结合如下策略: ✅ 使用 Parallel.ForEachAsync 并行处理内存数据。
Console.WriteLine($"{methodName}: count = {_count}"); } private void YanjiaIsComing(CancellationToken token) { Parallel.ForEachAsync
Console.WriteLine($"{methodName}: count = {_count}"); } private void YanjiaIsComing(CancellationToken token) { Parallel.ForEachAsync