The .NET Framework 4.0 release included PLINQ, an engine for parallel execution of LINQ queries. This technology provides considerable speed-up of LINQ to Objects query execution on multi-core machines, as it implicitly partitions the query data source into segments each being processed by a separate processor. To prepare a data source for parallel querying, one only needs to call the AsParallel extension method. For example, in the following code we get discontinued products (see the CRM Demo sample database) from the database, and process the resulting list in a parallel fashion:
C#csharp | ![]() |
---|---|
public static double XMasDiscountedPrice(double? price) { return price.GetValueOrDefault() / 2; } static void Main(string[] args) { //... var query = from product in context.Products where product.Discontinued.GetValueOrDefault() == true select product; var discontinuedProducts = query.ToList(); var productsForSale = from product in discontinuedProducts.AsParallel() // This is the place where PLINQ is enabled. select new { Name = product.ProductName, Price = XMasDiscountedPrice(product.Price) }; } |
Visual Basic | ![]() |
---|---|
Public Shared Function XMasDiscountedPrice(price As System.Nullable(Of Double)) As Double Return price.GetValueOrDefault() / 2 End Function Private Shared Sub Main(args As String()) '... Dim query = From product In context.Products Where product.Discontinued.GetValueOrDefault() = True Select product Dim discontinuedProducts = query.ToList() ' PLINQ is enabled at the .AsParallel() call Dim productsForSale = _ From product In discontinuedProducts.AsParallel() _ Select New With { _ Key .Name = product.ProductName, _ Key .Price = XMasDiscountedPrice(product.Price) _ } End Sub |
Notes on this sample:
LinqConnect supports the PLINQ engine, meaning that you can execute the AsParallel method on LinqConnect queries, causing the resulting collections to be processed in parallel. E.g., the above sample can be rewritten as
C#csharp | ![]() |
---|---|
public static double XMasDiscountedPrice(double? price) { return price.GetValueOrDefault() / 2; } static void Main(string[] args) { //... var query = from product in context.Products where product.Discontinued.GetValueOrDefault() == true select new { Name = product.ProductName, Price = XMasDiscountedPrice(product.Price) }; var productsForSale = query .AsParallel() // This is the place where PLINQ is enabled. .ToList(); } |
Visual Basic | ![]() |
---|---|
Public Shared Function XMasDiscountedPrice(price As System.Nullable(Of Double)) As Double Return price.GetValueOrDefault() / 2 End Function Private Shared Sub Main(args As String()) '... Dim query = _ From product In context.Products _ Where product.Discontinued.GetValueOrDefault() = True _ Select New With { _ Key .Name = product.ProductName, _ Key .Price = XMasDiscountedPrice(product.Price) _ } ' PLINQ is enabled at the .AsParallel() call Dim productsForSale = query _ .AsParallel() _ .ToList() End Sub |
What should be kept in mind when using PLINQ for LinqConnect queries is:
The AsParallel method should only be invoked on the 'final' queries, as after you call it, the rest of extension methods and LINQ expressions are considered to be of LINQ to SQL, not of LinqConnect. To explain what we mean saying this, let us apply AsParallel to the Products table in the previous sample:
C#csharp | ![]() |
---|---|
var query = from product in context.Products.AsParallel() where product.Discontinued.GetValueOrDefault() == true select new { Name = product.ProductName, Price = XMasDiscountedPrice(product.Price) }; var productsForSale = query.ToList(); |
Visual Basic | ![]() |
---|---|
Dim query = From product In context.Products.AsParallel() _ Where product.Discontinued.GetValueOrDefault() = True _ Select New With { _ Key .Name = product.ProductName, _ Key .Price = XMasDiscountedPrice(product.Price) _ } Dim productsForSale = query.ToList() |
As you can see, the generated SQL statement has no WHERE clause, i.e., all products are fetched to the client, and only then the limitation 'Discontinued == 1' is checked. The cause of this is that the parallel execution is enabled at the Products table, making context.Products.AsParallel() a local collection subject to LINQ to Objects processing.