Chapter 9: Async and Multithreading – Task-based Programming and Parallelism
In this chapter, we explore asynchronous programming and multithreading in C#.
These concepts are critical for building responsive, scalable, and high-performance applications.
🎯 What You Will Learn
By the end of this chapter, you will:
- Understand the difference between synchronous and asynchronous programming
- Learn about the Task Parallel Library (TPL)
- Use async/await for asynchronous operations
- Explore threads and the Thread class
- Implement parallel programming patterns with
Paralleland PLINQ - Practice hands-on exercises to reinforce learning
🔹 Synchronous vs Asynchronous Programming
Synchronous
- Code executes line by line.
- Blocks execution until a task completes.
Console.WriteLine("Start");
Thread.Sleep(2000); // Blocks for 2 seconds
Console.WriteLine("End");
Asynchronous
- Code executes without blocking.
- Frees up resources while waiting.
Console.WriteLine("Start");
await Task.Delay(2000); // Non-blocking wait
Console.WriteLine("End");
👉 Exercise:
- Write a synchronous program that downloads a file (simulate with
Thread.Sleep). - Convert it to asynchronous using
Task.Delay.
🔹 Task Parallel Library (TPL)
What is TPL?
- Provides high-level APIs for parallelism.
- Uses
Taskobjects to represent asynchronous operations.
Example:
using System;
using System.Threading.Tasks;
class Program
{
static void Main()
{
Task task = Task.Run(() =>
{
Console.WriteLine("Task running...");
});
task.Wait(); // Wait for completion
}
}
👉 Exercise:
- Create a task that calculates the sum of numbers from 1 to 1000.
🔹 Async and Await
Async Methods
- Declared with
asynckeyword. - Return
TaskorTask<T>.
Example:
using System;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
await PrintMessageAsync();
}
static async Task PrintMessageAsync()
{
await Task.Delay(2000);
Console.WriteLine("Hello from async method!");
}
}
👉 Exercise:
- Write an async method
DownloadDataAsync()that simulates downloading data withTask.Delay.
🔹 Threads in C#
Thread Class
- Represents a lightweight unit of execution.
Example:
using System;
using System.Threading;
class Program
{
static void PrintNumbers()
{
for (int i = 1; i <= 5; i++)
{
Console.WriteLine(i);
Thread.Sleep(500);
}
}
static void Main()
{
Thread t = new Thread(PrintNumbers);
t.Start();
Console.WriteLine("Main thread continues...");
}
}
👉 Exercise:
- Create two threads: one prints even numbers, the other prints odd numbers.
🔹 Parallel Programming
Parallel.For
using System;
using System.Threading.Tasks;
class Program
{
static void Main()
{
Parallel.For(1, 6, i =>
{
Console.WriteLine($"Iteration {i}");
});
}
}
Parallel.ForEach
string[] names = { "Alice", "Bob", "Charlie" };
Parallel.ForEach(names, name =>
{
Console.WriteLine($"Hello {name}");
});
👉 Exercise:
- Use
Parallel.Forto calculate squares of numbers from 1 to 10.
🔹 PLINQ (Parallel LINQ)
Example:
using System;
using System.Linq;
class Program
{
static void Main()
{
var numbers = Enumerable.Range(1, 20);
var evenSquares = numbers
.AsParallel()
.Where(n => n % 2 == 0)
.Select(n => n * n);
foreach (var square in evenSquares)
{
Console.WriteLine(square);
}
}
}
👉 Exercise:
- Use PLINQ to filter prime numbers from 1 to 100.
🔹 Synchronization
Locking Shared Resources
class Counter
{
private int count = 0;
private object lockObj = new object();
public void Increment()
{
lock (lockObj)
{
count++;
}
}
public int GetCount() => count;
}
👉 Exercise:
- Create a shared counter accessed by multiple threads.
- Use
lockto prevent race conditions.
📘 Chapter Summary
In this chapter, you learned:
- The difference between synchronous and asynchronous programming
- How to use the Task Parallel Library (TPL)
- How to implement async/await methods
- How to create and manage threads
- How to use Parallel.For, Parallel.ForEach, and PLINQ
- How to synchronize shared resources with
lock
👉 You also practiced exercises to reinforce learning.