C#中使用Parallel.For和Parallel.ForEach实现循环并行化
在C#开发中,当循环迭代彼此独立且运行于多核环境时,使用任务并行库(TPL)可显著提升性能。本文讲解如何使用Parallel.For和Parallel.ForEach实现并行循环,并解决并行执行导致的输出顺序错乱问题。
任务并行库的基本概念
在传统的C#编程中,我们通常使用 for 或 foreach 进行顺序循环。然而,当每一次迭代之间没有依赖关系时,将这些迭代分配到不同的处理器核心上并行执行,能够大幅缩短程序运行时间。任务并行库(Task Parallel Library, TPL)正是为此设计的,它简化了并行编程的复杂度。
第1步:使用Parallel.For实现并行循环
Parallel.For 适用于需要索引值的场景。其基本声明形式如下:
需要注意的是,Parallel.For 的范围参数通常为“左闭右开”区间(即包含起始值,不包含结束值)。例如,若传入0到5,实际处理的索引为 0、1、2、3、4。
示例代码:
static void Main(string[] args)
{
// 并行计算0到4的平方并打印
Parallel.For(0, 5, i =>
{
Console.WriteLine("The Square of {0} is {1}", i, i * i);
}
);
Console.ReadKey();
}由于线程调度的不确定性,上述代码的执行结果顺序将是随机的,而非从0到4递增:
The Square of 0 is 0
The Square of 2 is 4
The Square of 1 is 1
The Square of 4 is 16
The Square of 3 is 9
第2步:保持并行结果的有序性
如果业务逻辑要求结果必须按顺序输出,直接使用并行循环打印会导致顺序混乱。一种可靠的解决方法是预先分配一个固定大小的数组来存储每个索引对应的结果,因为数组索引本身具有天然的位置确定性。
示例代码:
static void Main(string[] args)
{
const int maxValues = 5;
// 预定义数组用于存储结果
int[] Squares = new int[maxValues];
// 并行计算并存入对应索引位置
Parallel.For(0, maxValues, i => Squares[i] = i * i);
// 随后按索引顺序遍历并输出,保证结果有序
for (int i = 0; i < maxValues; i++)
{
Console.WriteLine("Square of {0} is {1}", i, Squares[i]);
}
Console.ReadKey();
}通过这种方式,先利用并行计算填充数据,再串行读取数据,既享受了并行加速的优势,又保证了最终展示结果的顺序正确。
第3步:使用Parallel.ForEach遍历集合
对于非索引类型的集合(如字符串数组、列表等),Parallel.ForEach 是更合适的选择。它会遍历集合中的每个元素并执行委托操作。
示例代码:
static void Main(string[] args)
{
string[] squares = new string[]
{"We", "hold", "these", "truths", "to", "be", "self-evident",
"that", "all", "men", "are", "created", "equal"};
// 并行遍历每个单词,打印单词及其长度
Parallel.ForEach(squares,
item => Console.WriteLine("'{0}' has {1} letters", item, item.Length));
Console.ReadKey();
}
同样的,Parallel.ForEach 的输出也是无序的,因为线程执行的先后顺序不可控。如果需要对集合结果进行聚合排序后再输出,建议先将结果收集到列表或字典中,最后统一处理。
总结
Parallel.For 和 Parallel.ForEach 是 C# 中实现轻量级并行循环的有效工具。在使用时,请务必注意迭代之间的独立性以及输出顺序的需求。对于需要特定顺序的场景,采用“并行计算+串行输出”的模式(如数组索引映射)是简单且高效的解决方案。
以上就是C#使用Parallel.For和Parallel.ForEach实现循环并行化的详细内容,更多关于C#并行编程的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













