PLINQ (Parallel LINQ) is a parallelized implementation of LINQ (Language Integrated Query) that enables queries to execute in parallel, taking advantage of multi-core processors to improve performance.
Key Features of PLINQ
- Automatic Parallelization: PLINQ divides the data source into partitions and processes them on multiple threads automatically.
- Declarative Syntax: The syntax remains similar to LINQ, making it easier to use for developers familiar with LINQ.
- Scalability: PLINQ leverages all available processors for improved performance on large datasets.
- Customizable Execution: You can control the degree of parallelism and execution behavior.
Basic Example: Parallelizing a Query
using System;
using System.Linq;
class Program
{
static void Main()
{
var numbers = Enumerable.Range(1, 100);
// Parallel LINQ query
var evenNumbers = numbers
.AsParallel()
.Where(n => n % 2 == 0)
.ToList();
Console.WriteLine("Even numbers:");
evenNumbers.ForEach(Console.WriteLine);
}
}
Example: Measuring Performance
using System;
using System.Linq;
using System.Diagnostics;
class Program
{
static void Main()
{
var numbers = Enumerable.Range(1, 10_000_000).ToArray();
var stopwatch = new Stopwatch();
// Sequential processing
stopwatch.Start();
var sequentialSum = numbers.Where(n => n % 2 == 0).Sum();
stopwatch.Stop();
Console.WriteLine($"Sequential Sum: {sequentialSum}, Time: {stopwatch.ElapsedMilliseconds}ms");
// Parallel processing
stopwatch.Restart();
var parallelSum = numbers.AsParallel().Where(n => n % 2 == 0).Sum();
stopwatch.Stop();
Console.WriteLine($"Parallel Sum: {parallelSum}, Time: {stopwatch.ElapsedMilliseconds}ms");
}
}
Controlling Degree of Parallelism
using System;
using System.Linq;
class Program
{
static void Main()
{
var numbers = Enumerable.Range(1, 100);
var results = numbers
.AsParallel()
.WithDegreeOfParallelism(2) // Use 2 processors
.Where(n => n % 2 == 0)
.ToList();
results.ForEach(Console.WriteLine);
}
}
Handling Exceptions in PLINQ
using System;
using System.Linq;
class Program
{
static void Main()
{
var numbers = new[] { 1, 2, 3, 0, 5 };
try
{
var results = numbers.AsParallel()
.Select(n => 100 / n)
.ToList();
}
catch (AggregateException ex)
{
foreach (var innerException in ex.InnerExceptions)
{
Console.WriteLine(innerException.Message);
}
}
}
}
Preserving Order with PLINQ
using System;
using System.Linq;
class Program
{
static void Main()
{
var numbers = Enumerable.Range(1, 10);
var orderedResults = numbers
.AsParallel()
.AsOrdered()
.Where(n => n % 2 == 0)
.ToList();
Console.WriteLine("Ordered Results:");
orderedResults.ForEach(Console.WriteLine);
}
}
When to Use PLINQ?
- Computationally Intensive Tasks: PLINQ is suitable for tasks like image processing, mathematical computations, or large dataset analysis.
- Large Datasets: It works best when processing large collections that can benefit from parallel execution.
- Multi-Core Systems: PLINQ leverages the available CPU cores for parallel execution.
Limitations of PLINQ
- For small datasets or simple queries, the overhead of parallelization may outweigh the benefits.
- Avoid using PLINQ when queries modify shared state, as this can lead to race conditions.
- PLINQ runs on multiple threads, so ensure thread safety in operations.
Best Practices
- Measure performance using tools like Stopwatch to ensure PLINQ benefits your use case.
- Use AsOrdered only when necessary, as it introduces additional overhead.
- Handle exceptions using AggregateException.
PLINQ is a powerful tool for parallel processing, offering significant performance improvements when used correctly. It simplifies writing parallel code without needing to manage threads explicitly.

Join the conversation! Your thoughts help the community grow.