What is Multi-Threading?
Multi-threading allows your program to perform multiple operations concurrently, making better use of CPU resources and improving application responsiveness.
Real-life Analogy
Imagine a restaurant with multiple chefs (threads) in a kitchen. Each chef can work on a different dish (task) simultaneously. This allows the restaurant to serve multiple customers much faster than with just one chef.
Benefits of Multi-Threading:
- Improved responsiveness for UI applications
- Better utilization of multi-core processors
- Increased throughput for I/O-bound operations
- Simplified modeling of concurrent activities
Basic Multi-Threading Example
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main()
{
// Create multiple threads
Thread thread1 = new Thread(Task1);
Thread thread2 = new Thread(Task2);
// Start the threads
thread1.Start();
thread2.Start();
// Main thread continues working
for (int i = 0; i < 5; i++)
{
Console.WriteLine($"Main thread: {i}");
Thread.Sleep(100);
}
// Wait for threads to complete
thread1.Join();
thread2.Join();
Console.WriteLine("All threads completed");
}
static void Task1()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine($"Task1: {i}");
Thread.Sleep(200);
}
}
static void Task2()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine($"Task2: {i}");
Thread.Sleep(300);
}
}
}
Thread Visualization
In a multi-threaded application, different threads can execute different parts of your code simultaneously, making your application more responsive and efficient.
Types of Multi-Threading
1. Data Parallelism
Processing different pieces of data simultaneously across multiple threads
2. Task Parallelism
Executing different tasks or operations simultaneously
3. Pipeline Processing
Breaking work into stages with each stage handled by different threads
Thread Pool & TPL
The Thread Pool and Task Parallel Library (TPL) provide higher-level abstractions for multi-threading.
Using ThreadPool for Multi-Threading
using System;
using System.Threading;
class Program
{
static void Main()
{
// Queue multiple work items to the thread pool
for (int i = 0; i < 5; i++)
{
int taskNum = i; // Capture the loop variable
ThreadPool.QueueUserWorkItem(state =>
{
Console.WriteLine($"ThreadPool task {taskNum} executing on thread {Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(1000); // Simulate work
Console.WriteLine($"ThreadPool task {taskNum} completed");
});
}
Console.WriteLine("Main thread continues working...");
Thread.Sleep(3000); // Wait for tasks to complete
}
}
Task Parallel Library (TPL)
The TPL is a modern approach to multi-threading that makes it easier to write parallel and concurrent code.
Using Parallel.For for Data Parallelism
using System;
using System.Threading.Tasks;
class Program
{
static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Process array elements in parallel
Parallel.For(0, numbers.Length, i =>
{
Console.WriteLine($"Processing element {numbers[i]} on task {Task.CurrentId}");
// Simulate CPU-intensive work
Task.Delay(100).Wait();
numbers[i] = numbers[i] * 2; // Process the element
});
Console.WriteLine("Parallel processing completed");
Console.WriteLine("Results: " + string.Join(", ", numbers));
}
}
Using Parallel.Invoke for Task Parallelism
Parallel.Invoke(
() => {
Console.WriteLine("Task 1 executing");
Task.Delay(500).Wait();
},
() => {
Console.WriteLine("Task 2 executing");
Task.Delay(300).Wait();
},
() => {
Console.WriteLine("Task 3 executing");
Task.Delay(400).Wait();
}
);