| Threading in C# :👈 | 👉:Asynchronous Programming with async/await in C# |
Task Parallel Library (TPL) in C# |
Task Parallel Library (TPL) in C#
The Task Parallel Library (TPL) is a set of APIs within the System.Threading.Tasks namespace that simplifies adding parallelism and concurrency to C# applications. Introduced in .NET Framework 4.0, it provides a task-based model that is more efficient and scalable than traditional thread management.
Instead of manually creating and managing threads, the TPL uses a thread pool and automatically balances the workload across available processor cores. It manages complexities such as work partitioning, scheduling, load balancing, and exception handling.
Key Components of the TPL
1. Task and Task<TResult>
The Task class represents a single asynchronous operation. The generic Task<TResult> represents a task that returns a result of type TResult.
Example:
using System;
using System.Threading.Tasks;
public class TaskExample
{
public static void Main()
{
// Create and start a task that returns a result
Task<int> taskWithResult = Task.Run(() =>
{
Console.WriteLine("Task is calculating...");
return 10 * 10;
});
// Wait for the task to complete and get the result
int result = taskWithResult.Result;
Console.WriteLine($"Result from task: {result}");
}
}
2. The Parallel Class
The Parallel class provides static methods for executing loops in parallel, simplifying the process of parallelizing for and foreach loops.
Example: Parallel.ForEach
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
public class ParallelExample
{
public static void Main()
{
var items = new List<int> { 1, 2, 3, 4, 5 };
// Execute a loop in parallel
Parallel.ForEach(items, item =>
{
Console.WriteLine($"Processing item {item} on thread {Task.CurrentId}");
});
}
}
- Parallel.For: For numeric loops.
- Parallel.Invoke: Runs multiple
Actiondelegates in parallel.
3. async and await
Introduced in C# 5.0, async and await are built on top of the TPL, making asynchronous programming simpler and more readable. await pauses method execution until a Task completes without blocking the thread, ideal for I/O-bound tasks.
Example: async/await with TPL
using System;
using System.Net.Http;
using System.Threading.Tasks;
public class AsyncExample
{
public static async Task Main()
{
Console.WriteLine("Main thread started.");
var httpClient = new HttpClient();
// Await the completion of an I/O-bound task
string html = await httpClient.GetStringAsync("https://example.com");
Console.WriteLine($"Web page downloaded. HTML length: {html.Length}");
Console.WriteLine("Main thread finished.");
}
}
4. Task Coordination
The TPL provides methods to coordinate multiple tasks:
- Task.WhenAll: Completes when all provided tasks are finished.
- Task.WhenAny: Completes when any one of the provided tasks finishes.
π§ What Is TPL?
The Task Parallel Library (TPL) is a set of public types and APIs in the System.Threading and System.Threading.Tasks namespaces that simplify writing multithreaded and parallel code. It abstracts away the complexity of thread management, making it easier to write scalable and efficient applications.
π Version Introduced
π TPL was introduced in .NET Framework 4.0, released in 2010. It has since become the preferred way to write parallel and asynchronous code in .NET, including .NET Core and .NET 5+.
βοΈ Key Features of TPL
- Task-based programming model (
Task,Task<T>) - Parallel loops (
Parallel.For,Parallel.ForEach) - Task composition (
Task.WhenAll,Task.WhenAny) - Cancellation support (
CancellationToken) - Exception handling for aggregated exceptions
- Thread pool management (automatic scaling)
π§ͺ Examples
πΉ Task Creation
Task task = Task.Run(() => Console.WriteLine("Running in parallel"));
πΉ Parallel Loop
Parallel.For(0, 5, i => Console.WriteLine($"Iteration {i}"));
πΉ Task with Return Value
Task<int> task = Task.Run(() => 42);
int result = task.Result; // Blocks until completed
πΉ Task Composition
Task.WhenAll(
Task.Run(() => Console.WriteLine("Task 1")),
Task.Run(() => Console.WriteLine("Task 2"))
).Wait();
πΉ Cancellation
var cts = new CancellationTokenSource();
Task.Run(() => {
while (!cts.Token.IsCancellationRequested) {
Console.WriteLine("Working...");
}
}, cts.Token);
cts.Cancel(); // Request cancellation
β Best Practices
- Use
async/awaitwithTaskfor asynchronous workflows. - Prefer
Task.Runover manually creating threads. - Use
ConfigureAwait(false)in library code to avoid deadlocks. - Avoid blocking calls like
.Wait()or.Resultin async code. - Use
CancellationTokenfor cooperative cancellation.
π When to Use
- For CPU-bound operations that benefit from parallelism.
- To keep UI responsive in desktop or mobile apps.
- In server-side applications to handle concurrent requests.
- For data processing, simulations, or batch jobs.
π« When Not to Use
- For I/O-bound operations β use
async/awaitinstead. - When parallelism adds more overhead than performance benefit.
- In ASP.NET Core controllers β theyβre already parallelized.
- For short-lived tasks that donβt justify thread creation.
β οΈ Precautions
- Avoid over-parallelizing β can lead to thread starvation.
- Handle
AggregateExceptionwhen usingTask.Wait()or.Result. - Be cautious with shared state β use locks or thread-safe collections.
- Monitor performance β parallelism isnβt always faster.
π― Advantages
- β Simplifies parallel and asynchronous programming
- β Automatically manages thread pooling
- β Scales with processor cores
- β Improves performance and responsiveness
- β
Integrates seamlessly with
async/await - Simplicity: Focus on logic instead of thread management.
- Efficiency and scalability: Uses thread pooling and multi-core processors effectively.
- Robust error handling: Exceptions are aggregated in an
AggregateException. - Cooperative cancellation: Safe task cancellation with
CancellationTokenSource.
Limitations and Considerations
- Overhead: Small, short loops may not benefit due to parallelization overhead.
- Not for I/O-bound operations: Use
async/awaitinstead ofParallelconstructs. - Complexity: Shared resource management is still required to avoid race conditions.
π Conclusion
The Task Parallel Library (TPL) revolutionized how developers write concurrent code in C#. Introduced in .NET Framework 4.0, it provides a high-level, flexible, and efficient model for parallelism. Whether you're building desktop apps, web services, or data pipelines, TPL helps you harness the power of modern multicore processors with minimal effort.
| Threading in C# :👈 | 👉:Asynchronous Programming with async/await in C# |