在C#的并行编程场景中,PLINQ可以让开发者快速将普通的LINQ查询转换为并行执行的查询,提升数据处理效率。而WithDegreeOfParallelism方法是调整PLINQ并行执行任务数量的核心方法,合理设置这个方法的参数,能让并行查询在性能和资源占用之间达到平衡。

WithDegreeOfParallelism方法的基本定义
WithDegreeOfParallelism是ParallelQuery<TSource>类型的扩展方法,它的作用是设置并行查询中可以同时执行的最大任务数。方法的参数是一个int类型的数值,代表并行度上限。需要注意的是,这个数值并不是一定会生效,PLINQ运行时还会根据系统的CPU核心数、当前负载等情况做动态调整。
方法签名说明
方法的官方定义如下,其中degreeOfParallelism就是我们要设置的并行度参数:
public static ParallelQuery<TSource> WithDegreeOfParallelism<TSource>(
this ParallelQuery<TSource> source,
int degreeOfParallelism
)
并行度设置的核心原则
设置WithDegreeOfParallelism的参数时,不能盲目选择数值,需要结合实际的任务场景和系统环境考虑,核心原则有以下几点:
- 并行度不能超过当前环境的逻辑CPU核心数,超过部分不会提升性能,反而会增加线程调度的开销
- 如果任务是计算密集型,并行度建议设置为逻辑核心数或者逻辑核心数减1,预留一个核心给系统其他任务
- 如果任务是IO密集型,比如涉及文件读写、网络请求,并行度可以适当提高,因为线程在等待IO时会释放CPU资源
- 不要设置过高的并行度,过多的并行任务会导致线程上下文切换频繁,反而降低整体执行效率
实际代码示例
下面通过一个计算密集型任务的示例,展示不同并行度设置下的执行效果。我们使用一个循环计算大量数据的平方和,分别测试并行度为1、4、8时的执行时间:
using System;
using System.Diagnostics;
using System.Linq;
class Program
{
static void Main()
{
// 生成100万个测试数据
var data = Enumerable.Range(1, 1000000).ToArray();
var stopwatch = new Stopwatch();
// 测试并行度为1的情况,相当于串行执行
stopwatch.Start();
var result1 = data.AsParallel()
.WithDegreeOfParallelism(1)
.Select(x => x * x)
.Sum();
stopwatch.Stop();
Console.WriteLine($"并行度为1的执行时间:{stopwatch.ElapsedMilliseconds}毫秒");
// 测试并行度为4的情况
stopwatch.Restart();
var result2 = data.AsParallel()
.WithDegreeOfParallelism(4)
.Select(x => x * x)
.Sum();
stopwatch.Stop();
Console.WriteLine($"并行度为4的执行时间:{stopwatch.ElapsedMilliseconds}毫秒");
// 测试并行度为8的情况,假设当前环境有8个逻辑核心
stopwatch.Restart();
var result3 = data.AsParallel()
.WithDegreeOfParallelism(8)
.Select(x => x * x)
.Sum();
stopwatch.Stop();
Console.WriteLine($"并行度为8的执行时间:{stopwatch.ElapsedMilliseconds}毫秒");
}
}
在8核CPU的环境下运行上述代码,通常可以看到并行度为4和8的执行时间明显低于并行度为1的情况,而并行度为8的执行时间可能和并行度为4的差距不大,甚至偶尔会更慢,这就是因为线程调度开销增加导致的。
常见误区说明
很多开发者会误以为并行度设置得越高,执行速度就越快,这是不正确的。当并行度超过CPU核心数时,多余的线程会处于等待状态,线程上下文切换的成本会抵消并行带来的收益。另外,WithDegreeOfParallelism设置的是最大并行度,不是固定并行度,PLINQ运行时可能会根据数据量和系统负载减少实际并行的任务数。
如果不确定该设置多少并行度,可以先通过测试不同数值的执行时间,选择最优的参数。对于大多数计算密集型场景,将并行度设置为逻辑CPU核心数是比较稳妥的选择。
PLINQWithDegreeOfParallelismC_Sharp并行编程修改时间:2026-07-01 05:15:29