| Attributes in C# | Task Parallel Library (TPL) in C# | |
🧵 Threading & Multithreading in C# |
In C#, a thread is a single sequence of instructions executed by a program. Threading is the practice of managing these individual execution paths. A standard C# application begins with a single, primary thread that performs all operations sequentially. Multithreading is the ability to run two or more threads concurrently within a single program.
This improves performance and responsiveness, allowing tasks to run in the background while the main thread handles user interactions.
| Feature | Modern approach (Tasks/async/await) | Classic approach (Thread class) |
|---|---|---|
| Abstraction | Higher-level. A Task represents an asynchronous operation, not a physical thread. |
Low-level. You manually create and manage each Thread object. |
| Efficiency | Tasks use a thread pool to reuse threads, reducing overhead. | Creating new Thread objects is expensive. |
| Resource | Optimized for CPU-bound and I/O-bound work. | Best suited for long-running, dedicated tasks. |
| Error handling | Tasks aggregate exceptions; await simplifies handling. |
Exceptions must be handled explicitly inside the thread. |
| Cancellation | Uses CancellationToken for safe cancellation. |
Thread.Abort() is unsafe and obsolete. |
When multiple threads access shared data, race conditions can occur. To prevent this, C# provides several synchronization primitives:
ConcurrentDictionary.This modern approach is recommended for most multithreading scenarios, especially I/O-bound operations.
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
public static int PerformCpuWork()
{
Console.WriteLine("CPU-bound work starting...");
Thread.Sleep(3000);
Console.WriteLine("CPU-bound work finished.");
return 42;
}
public static async Task<string> PerformIoWorkAsync()
{
Console.WriteLine("I/O-bound work starting...");
await Task.Delay(2000);
Console.WriteLine("I/O-bound work finished.");
return "Data from I/O";
}
public static async Task Main()
{
Console.WriteLine("Main thread: Program started.");
Task<int> cpuTask = Task.Run(() => PerformCpuWork());
Task<string> ioTask = PerformIoWorkAsync();
Console.WriteLine("Main thread: Continuing with other tasks...");
string ioResult = await ioTask;
int cpuResult = await cpuTask;
Console.WriteLine($"\nMain thread: Received I/O result: {ioResult}");
Console.WriteLine($"Main thread: Received CPU result: {cpuResult}");
Console.WriteLine("Main thread: Program finished.");
}
}
Threading in C# allows your application to perform multiple tasks concurrently. A thread is the smallest unit of execution, and multithreading enables multiple threads to run in parallel, improving responsiveness and performance.
using System;
using System.Threading;
class Program {
static void PrintNumbers() {
for (int i = 1; i <= 5; i++) {
Console.WriteLine("Worker Thread: " + i);
Thread.Sleep(500);
}
}
static void Main() {
Thread t1 = new Thread(PrintNumbers);
t1.Start();
for (int i = 1; i <= 5; i++) {
Console.WriteLine("Main Thread: " + i);
Thread.Sleep(500);
}
}
}
using System.Threading.Tasks;
Task.Run(() => {
Console.WriteLine("Running in a separate thread");
});
lock to prevent race conditions.Monitor, Mutex, or Semaphore for advanced control.Task and async/await for modern multithreading.ConcurrentDictionary.Threading and multithreading in C# are essential for building responsive, high-performance applications. By understanding how threads work and applying best practices, you can unlock powerful concurrency features while avoiding common pitfalls.
| Attributes in C# | Task Parallel Library (TPL) in C# | |