Parallel.ForEach 是 .NET Framework 4.0 引入的并行編程功能的一部分,位于 System.Threading.Tasks 命名空間中。它允許你對集合中的元素進行并行處理,可以顯著提高處理大量數據時的性能。
基本用法
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
Parallel.ForEach(numbers, new ParallelOptions { MaxDegreeOfParallelism = 4 }, number =>
{Console.WriteLine($"Processing {number} with MaxDegreeOfParallelism = 4");
});
2. 使用 ParallelOptions 控制并行度
var options = new ParallelOptions
{MaxDegreeOfParallelism = Environment.ProcessorCount * 2, // 限制最大并行度CancellationToken = cancellationTokenSource.Token // 取消支持
};Parallel.ForEach(numbers, options, number =>
{// 處理邏輯
});
3. 帶本地初始化和最終合并
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
性能考慮
// 測量并行與非并行版本的性能差異
Stopwatch stopwatch = Stopwatch.StartNew();// 并行版本
Parallel.ForEach(numbers, number =>
{// 耗時操作
});stopwatch.Stop();
Console.WriteLine($"Parallel version took {stopwatch.ElapsedMilliseconds} ms");
實際應用示例
// 處理大量文件
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 密集型任務。正確使用時可以顯著提高性能,但需要注意線程安全、資源管理和異常處理等問題。