在C#的并行编程体系中,Parallel类位于System.Threading.Tasks命名空间下,它提供了一组简化并行操作的方法,能够让开发者无需手动管理线程,就可以轻松实现多核CPU的资源利用。通过Parallel类执行的操作会自动根据当前CPU的核心数量拆分任务,分配到不同的核心上并行处理,大幅减少任务的总执行时间。

Parallel类的核心使用场景
1. 并行执行For循环
当我们需要对一个集合或者区间内的元素执行相同的操作时,可以使用Parallel.For替代普通的for循环,实现循环的并行执行。以下是一个简单的示例,计算1到1000的数值平方和:
using System;
using System.Threading.Tasks;
class Program
{
static void Main()
{
long totalSum = 0;
// 并行执行1到1000的循环,i从1开始,到1000结束(不包含1000)
Parallel.For(1, 1000, i =>
{
// 每个迭代计算i的平方,累加到总和中
// 注意:实际场景需要考虑线程安全的累加方式,这里仅为示例
totalSum += i * i;
});
Console.WriteLine($"1到999的平方总和为:{totalSum}");
}
}
需要注意的是,上面的示例中直接对totalSum进行累加存在线程安全问题,多个并行任务同时修改该变量会导致结果不准确。正确的做法可以使用Interlocked类或者局部变量累加后再合并的方式,修改后的代码如下:
using System;
using System.Threading.Tasks;
using System.Threading;
class Program
{
static void Main()
{
long totalSum = 0;
Parallel.For(1, 1000, () => 0L, (i, loopState, localSum) =>
{
// 每个线程维护自己的局部累加值
localSum += i * i;
return localSum;
}, localSum =>
{
// 所有线程的局部累加值完成后,合并到总结果中
Interlocked.Add(ref totalSum, localSum);
});
Console.WriteLine($"1到999的平方总和为:{totalSum}");
}
}
2. 并行执行Foreach循环
如果需要对一个集合中的每个元素执行相同的操作,可以使用Parallel.ForEach方法,它和普通的foreach循环逻辑类似,但是会并行处理集合中的元素。以下是一个处理字符串集合的示例:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
class Program
{
static void Main()
{
List<string> dataList = new List<string>();
// 初始化测试数据,添加100个字符串
for (int i = 0; i < 100; i++)
{
dataList.Add($"测试数据{i}");
}
// 并行遍历集合中的每个元素
Parallel.ForEach(dataList, item =>
{
// 模拟每个元素的处理逻辑,这里打印元素内容
Console.WriteLine($"正在处理:{item}");
});
}
}
3. 并行执行多个独立任务
如果有一组相互独立的任务需要同时执行,可以使用Parallel.Invoke方法,它可以接收多个Action委托,并行执行这些委托对应的任务。示例如下:
using System;
using System.Threading.Tasks;
class Program
{
static void Main()
{
// 并行执行三个独立的任务
Parallel.Invoke(
() => TaskOne(),
() => TaskTwo(),
() => TaskThree()
);
Console.WriteLine("所有并行任务执行完成");
}
static void TaskOne()
{
Console.WriteLine("任务一执行中");
}
static void TaskTwo()
{
Console.WriteLine("任务二执行中");
}
static void TaskThree()
{
Console.WriteLine("任务三执行中");
}
}
使用Parallel类的注意事项
- 不是所有场景都适合用Parallel类,如果单个迭代的执行时间非常短,并行带来的线程调度开销可能会抵消性能提升,甚至导致程序变慢。
- 并行执行的迭代顺序是不确定的,不能依赖循环的执行顺序来编写业务逻辑。
- 并行操作中如果涉及到共享资源的修改,必须做好线程安全处理,避免出现数据不一致的问题。
- 可以通过
ParallelOptions类设置并行的最大线程数,避免过多线程占用系统资源,示例如下:
using System;
using System.Threading.Tasks;
class Program
{
static void Main()
{
ParallelOptions options = new ParallelOptions
{
// 设置最大并行度为4,最多使用4个线程执行并行任务
MaxDegreeOfParallelism = 4
};
Parallel.For(1, 1000, options, i =>
{
Console.WriteLine($"当前迭代值:{i}");
});
}
}
合理使用Parallel类能够让C#程序充分利用多核CPU的计算能力,在处理批量计算、批量数据处理等场景时,能显著提升程序的执行效率。开发者需要根据实际的业务场景选择合适的并行方式,同时注意规避并行编程中的常见问题,才能让并行编程发挥最大的价值。