71、C# Parallel.ForEach 详解

Parallel.ForEach 是 .NET Framework 4.0 引入的并行编程功能的一部分,位于 System.Threading.Tasks 命名空间中。它允许你对集合中的元素进行并行处理,可以显著提高处理大量数据时的性能。

基本用法

csharp 复制代码
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        
        // 基本形式
        Parallel.ForEach(numbers, number =>
        {
            Console.WriteLine($"Processing {number} on thread {Thread.CurrentThread.ManagedThreadId}");
            // 处理逻辑
        });
    }
}

高级用法

1. 带分区器的 Parallel.ForEach

csharp 复制代码
Parallel.ForEach(numbers, new ParallelOptions { MaxDegreeOfParallelism = 4 }, number =>
{
    Console.WriteLine($"Processing {number} with MaxDegreeOfParallelism = 4");
});

2. 使用 ParallelOptions 控制并行度

csharp 复制代码
var options = new ParallelOptions
{
    MaxDegreeOfParallelism = Environment.ProcessorCount * 2, // 限制最大并行度
    CancellationToken = cancellationTokenSource.Token // 取消支持
};

Parallel.ForEach(numbers, options, number =>
{
    // 处理逻辑
});

3. 带本地初始化和最终合并

csharp 复制代码
Parallel.ForEach<int, long>(numbers, 
    () => 0, // 本地初始化
    (number, loopState, localSum) =>
    {
        // 处理逻辑并返回本地状态
        localSum += number;
        return localSum;
    },
    (finalSum) =>
    {
        // 最终合并
        Console.WriteLine($"Partial sum: {finalSum}");
        Interlocked.Add(ref totalSum, finalSum);
    });

重要参数和特性

  • MaxDegreeOfParallelism:控制最大并行任务数
  • CancellationToken:支持取消操作
  • 分区策略:自动将集合划分为多个分区,默认使用范围分区
  • 异常处理:并行循环中的异常会被收集到 AggregateException 中

注意事项

  • 线程安全:确保对共享资源的访问是线程安全的
  • 顺序不保证:处理顺序与集合顺序无关
  • 资源消耗:过度并行化可能导致性能下降
  • 异常处理:需要适当处理 AggregateException

性能考虑

csharp 复制代码
// 测量并行与非并行版本的性能差异
Stopwatch stopwatch = Stopwatch.StartNew();

// 并行版本
Parallel.ForEach(numbers, number =>
{
    // 耗时操作
});

stopwatch.Stop();
Console.WriteLine($"Parallel version took {stopwatch.ElapsedMilliseconds} ms");

实际应用示例

csharp 复制代码
// 处理大量文件
string[] files = Directory.GetFiles(@"C:\LargeFolder");

Parallel.ForEach(files, file =>
{
    try
    {
        ProcessFile(file);
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error processing {file}: {ex.Message}");
    }
});

替代方案比较

  • Parallel.ForEach:适用于数据并行场景,自动分区
  • Task.WhenAll:适用于异步操作,更灵活的控制
  • PLINQ:适用于查询场景,语法更简洁

总结

Parallel.ForEach 是处理可并行化集合操作的强大工具,特别适合 CPU 密集型任务。正确使用时可以显著提高性能,但需要注意线程安全、资源管理和异常处理等问题。

相关推荐
时光追逐者2 小时前
C#拾遗补漏之 Dictionary 详解
开发语言·c#·.net·.net core
q__y__L9 小时前
C#线程同步(二)锁
开发语言·性能优化·c#
Yueeyuee_12 小时前
【C#学习Day15笔记】拆箱装箱、 Equals与== 、文件读取IO
笔记·学习·c#
R-G-B14 小时前
【33】C# WinForm入门到精通 ——表格布局器TableLayoutPanel【属性、方法、事件、实例、源码】
开发语言·c#·c# winform·表格布局器·tablelayoutpane
freesheep72014 小时前
WPF使用PreviewTextInput事件限制用户输入
c#·wpf
Yueeyuee_17 小时前
【C#学习Day16笔记】XML文件、 事件Event 、Json数据
笔记·学习·c#
钢铁男儿20 小时前
C# 枚举器和迭代器(常见迭代器模式)
数据库·c#·迭代器模式
R-G-B1 天前
【05】VM二次开发——模块参数配置--带渲染/不带渲染(WinForm界面调用 模块参数配置)
c#·vm二次开发·vm模块参数配置·vm在winform界面调用
R-G-B1 天前
【12】大恒相机SDK C#开发 ——多相机开发,枚举所有相机,并按配置文件中的相机顺序 将所有相机加入设备列表,以便于对每个指定的相机操作
c#·大恒相机sdk·大恒多相机开发·大恒多相机枚举·大恒多相机指定顺序
R-G-B1 天前
【13】大恒相机SDK C#开发 —— Fom1中实时处理的8个图像 实时显示在Form2界面的 pictureBox中
c#·大恒相机sdk·图像实时显示在另一个界面