在现代软件开发中,随着多核处理器的普及,利用并行计算来提高程序性能变得越来越重要。PLINQ(Parallel LINQ)是.NET框架中一个强大的工具,它允许开发者以几乎不需要修改现有代码的方式,将LINQ查询转换为并行执行。本文将介绍PLINQ的基本概念、使用方法以及如何控制并行执行。
PLINQ是LINQ的一个扩展,它为LINQ-to-Objects和LINQ-to-XML查询提供了并行执行的能力。当系统中有多个处理器或核心可用时,PLINQ会自动利用它们来执行查询。使用PLINQ几乎与使用LINQ-to-Objects和LINQ-to-XML相同,可以使用C# 3.0语法或System.Linq.Enumerable类中的任何操作符,包括OrderBy、Join、Select、Where等。
要开始使用PLINQ,需要使用AsParallel方法。这个方法将数据序列转换为ParallelQuery,当LINQ引擎检测到查询的源是ParallelQuery时,它会自动切换到PLINQ执行。以下是使用AsParallel方法的示例代码:
var customers = new[] {
new Customer { ID = 1, FirstName = "Sandeep", LastName = "Ramani" },
// ... 更多客户数据 ...
new Customer { ID = 20, FirstName = "Nilesh", LastName = "Soni" }
};
var results = from c in customers.AsParallel()
where c.FirstName.StartsWith("San")
select c;
通过简单地添加AsParallel()扩展方法,.NET运行时将自动在多个核心上并行化操作。实际上,PLINQ将负责将数据分割成可以并行处理的多个块。
PLINQ仅适用于本地集合。这意味着,如果使用的是远程数据的LINQ提供程序,如LINQ to SQL或ADO.NETEntity Framework,那么PLINQ就无法并行化这些查询。由于PLINQ将集合分割成多个分区并并行执行它们,因此PLINQ查询的结果可能与串行执行的LINQ查询的结果顺序不同。
在某些情况下,PLINQ可能会决定查询更适合顺序执行。可以通过使用WithExecutionMode扩展方法来控制这一点,该方法应用于ParallelQuery类型。WithExecutionMode方法接受ParallelExecutionMode枚举的一个值。有两个这样的值:默认值(让PLINQ决定该怎么做)和ForceParallelism(即使并行执行的开销可能大于好处,也使用PLINQ)。
var results = from c in customers.AsParallel().WithExecutionMode(ParallelExecutionMode.ForceParallelism)
where c.FirstName.StartsWith("San")
select c;
还可以请求PLINQ限制同时处理的分区数量,使用WithDegreeOfParallelism扩展方法,该方法操作ParallelQuery类型。这个方法接受一个int参数,指定应该同时处理的最大分区数量;这被称为并行度。设置并行度并不会强制PLINQ使用那么多。它只是设置了一个上限。PLINQ可能会决定使用比指定的更少的分区,或者,如果没有使用WithExecutionMode方法,可能会决定顺序执行查询。
var results = from c in customers.AsParallel().WithDegreeOfParallelism(2)
where c.FirstName.StartsWith("San")
select c;
以下代码使用Range方法创建了一个从0开始的50,000个整数的序列。方法的第一个参数是起始索引;第二个是需要的值的数量。注意已将Range方法的结果转换为ParallelQuery。如果不这样做,LINQ不会识别该序列支持并行执行,并将顺序执行查询。
IEnumerable evens = ((ParallelQuery)ParallelEnumerable.Range(0, 50000))
.Where(i => i % 2 == 0)
.Select(i => i);
以下代码使用Repeat方法创建了一个重复指定次数的对象序列。
int sum = ParallelEnumerable.Repeat(1, 50000)
.Select(i => i)
.Sum();
静态Repeat方法接受一个对象和一个计数,并创建一个序列,其中该对象重复了指定的次数。
本文介绍了PLINQ的基本概念、使用方法以及如何控制并行执行。希望这篇文章能帮助开始使用PLINQ,并从中获得一些知识。