导读:本期聚焦于小伙伴创作的《C#中Parallel.ForEachAsync怎么用?.NET 6并行异步循环教程》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#中Parallel.ForEachAsync怎么用?.NET 6并行异步循环教程》有用,将其分享出去将是对创作者最好的鼓励。

在.NET 6中,C#新增了Parallel.ForEachAsync方法,专门用于并行执行异步操作,解决了传统foreach循环串行执行异步任务效率不足的问题,也弥补了普通Parallel.ForEach无法处理异步委托的缺陷。该方法可以同时对多个元素执行异步操作,并且支持自定义并行度,适合处理批量IO密集型或网络请求类的异步任务。

C#中Parallel.ForEachAsync怎么用?.NET 6并行异步循环教程

Parallel.ForEachAsync基本语法

Parallel.ForEachAsync的核心作用是遍历一个集合,对每个元素执行异步委托,并且多个元素的异步操作可以并行执行。它的基本方法签名如下:

public static System.Threading.Tasks.Task ForEachAsync<TSource> (
    System.Collections.Generic.IEnumerable<TSource> source,
    System.Func<TSource,int,System.Threading.CancellationToken,System.Threading.Tasks.Task> body
)

其中source是要遍历的集合,body是处理每个元素的异步委托,委托参数包含当前元素、元素索引和取消令牌。如果需要控制并行度,还可以传入ParallelOptions参数:

public static System.Threading.Tasks.Task ForEachAsync<TSource> (
    System.Collections.Generic.IEnumerable<TSource> source,
    System.Threading.Tasks.ParallelOptions parallelOptions,
    System.Func<TSource,int,System.Threading.CancellationToken,System.Threading.Tasks.Task> body
)

基础使用示例

下面通过一个简单的示例演示Parallel.ForEachAsync的基本用法,场景是批量请求接口获取不同用户的信息,使用并行异步循环提升请求效率:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        // 待处理的用户ID集合
        List<int> userIds = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        
        Console.WriteLine($"开始执行并行异步循环,时间:{DateTime.Now:HH:mm:ss.fff}");
        
        // 使用Parallel.ForEachAsync并行处理每个用户ID
        await Parallel.ForEachAsync(userIds, async (userId, cancellationToken) =>
        {
            // 模拟异步请求接口获取用户信息,耗时1秒
            await Task.Delay(1000, cancellationToken);
            Console.WriteLine($"处理用户ID:{userId},完成时间:{DateTime.Now:HH:mm:ss.fff}");
        });
        
        Console.WriteLine($"所有任务完成,时间:{DateTime.Now:HH:mm:ss.fff}");
    }
}

执行上述代码后会发现,10个用户ID的处理完成时间大约在1秒左右,因为默认并行度会根据系统CPU核心数自动调整,多个异步任务同时执行。如果使用普通foreach循环串行执行,完成时间会接近10秒。

控制并行度

默认情况下Parallel.ForEachAsync的并行度由运行时自动决定,如果需要手动限制同时执行的异步任务数量,可以通过ParallelOptionsMaxDegreeOfParallelism属性设置:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        List<int> userIds = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        
        // 创建并行配置,设置最大并行度为3
        ParallelOptions options = new ParallelOptions
        {
            MaxDegreeOfParallelism = 3
        };
        
        Console.WriteLine($"开始执行,最大并行度3,时间:{DateTime.Now:HH:mm:ss.fff}");
        
        await Parallel.ForEachAsync(userIds, options, async (userId, cancellationToken) =>
        {
            await Task.Delay(1000, cancellationToken);
            Console.WriteLine($"处理用户ID:{userId},完成时间:{DateTime.Now:HH:mm:ss.fff}");
        });
        
        Console.WriteLine($"所有任务完成,时间:{DateTime.Now:HH:mm:ss.fff}");
    }
}

设置最大并行度为3后,同时最多只有3个异步任务在执行,10个任务会分4批完成,总耗时大约4秒,适合需要限制资源占用的场景,比如避免同时发起过多网络请求导致服务端压力过大。

异常处理

Parallel.ForEachAsync执行过程中如果某个元素的异步操作抛出异常,所有正在执行的任务会被取消,剩余的未执行元素不会再处理,并且异常会被包装为AggregateException抛出。可以使用try-catch捕获异常并处理:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
        
        try
        {
            await Parallel.ForEachAsync(numbers, async (num, cancellationToken) =>
            {
                if (num == 3)
                {
                    // 模拟第三个元素处理时抛出异常
                    throw new InvalidOperationException($"处理数字{num}时发生错误");
                }
                await Task.Delay(500, cancellationToken);
                Console.WriteLine($"成功处理数字:{num}");
            });
        }
        catch (AggregateException ex)
        {
            // 遍历所有内部异常
            foreach (var innerEx in ex.InnerExceptions)
            {
                Console.WriteLine($"捕获到异常:{innerEx.Message}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"捕获到其他异常:{ex.Message}");
        }
    }
}

和其他循环方式的区别

很多开发者会混淆Parallel.ForEachAsync和以下几种循环方式,这里做简单对比:

循环方式是否支持异步委托是否并行执行适用场景
foreach + await需要串行执行异步任务的场景
Parallel.ForEach处理CPU密集型的同步任务
Parallel.ForEachAsync处理批量IO密集型或网络类的异步任务

注意事项

  • Parallel.ForEachAsync只支持.NET 6及以上版本,低版本框架无法使用。
  • 不要在body委托中执行长时间阻塞线程的同步操作,否则会失去并行的优势,甚至导致线程池耗尽。
  • 如果需要保证元素的执行顺序和结果顺序一致,Parallel.ForEachAsync无法保证,需要额外处理顺序逻辑。
  • 合理设置MaxDegreeOfParallelism,过高的并行度可能会导致系统资源过载,反而降低整体效率。

C#Parallel_ForEachAsync.NET_6异步循环修改时间:2026-07-22 15:30:32

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。