Here are five real-world project-based exercises to master concurrency and parallel programming in C#. Each project comes with an overview, objectives, and hands-on tasks.
🚀 Project 1: High-Performance Web Scraper (Async & Parallel)
Overview
Build a multi-threaded web scraper that fetches data from multiple websites in parallel.
Objectives
✅ Use HttpClient with async/await
✅ Implement Parallel.ForEachAsync() for faster data retrieval
✅ Use ConcurrentBag to store results safely
Implementation Steps
1️⃣ Create a list of URLs to scrape.
2️⃣ Fetch data asynchronously using HttpClient
.
3️⃣ Use Parallel.ForEachAsync()
for concurrent requests.
4️⃣ Store results in ConcurrentBag
.
Code Example
using System;
using System.Collections.Concurrent;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
string[] urls = {
"https://jsonplaceholder.typicode.com/posts/1",
"https://jsonplaceholder.typicode.com/posts/2",
"https://jsonplaceholder.typicode.com/posts/3"
};
ConcurrentBag<string> results = new ConcurrentBag<string>();
await Parallel.ForEachAsync(urls, async (url, _) =>
{
using HttpClient client = new HttpClient();
string content = await client.GetStringAsync(url);
results.Add(content);
Console.WriteLine($"Fetched data from {url}");
});
Console.WriteLine($"Total responses: {results.Count}");
}
}
🔹 Enhancement: Store the results in a database or cache (Redis).
🚀 Project 2: Multi-Threaded File Processor
Overview
Process multiple large files concurrently.
Objectives
✅ Read multiple files asynchronously
✅ Use Parallel.ForEach() to process files in parallel
✅ Implement progress tracking
Implementation Steps
1️⃣ Read file names from a directory.
2️⃣ Use Parallel.ForEach()
to process files.
3️⃣ Store results in a thread-safe collection.
Code Example
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Threading.Tasks;
class Program
{
static void ProcessFile(string filePath)
{
string content = File.ReadAllText(filePath);
Console.WriteLine($"Processed: {filePath} (Length: {content.Length})");
}
static void Main()
{
string[] files = Directory.GetFiles("C:\\Logs", "*.log");
Parallel.ForEach(files, ProcessFile);
Console.WriteLine("All files processed.");
}
}
🔹 Enhancement: Save processed data in a database or cloud storage.
🚀 Project 3: Concurrent Order Processing System (Producer-Consumer)
Overview
Simulate a high-performance order processing system.
Objectives
✅ Implement the Producer-Consumer pattern
✅ Use BlockingCollection
for safe multi-threaded queueing
✅ Optimize performance with ThreadPool
Implementation Steps
1️⃣ The Producer generates orders and adds them to a queue.
2️⃣ The Consumer processes orders concurrently.
3️⃣ Use BlockingCollection
for thread-safe queueing.
Code Example
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static BlockingCollection<string> orderQueue = new BlockingCollection<string>();
static void OrderProducer()
{
for (int i = 1; i <= 10; i++)
{
orderQueue.Add($"Order-{i}");
Console.WriteLine($"Added Order-{i}");
Thread.Sleep(100);
}
orderQueue.CompleteAdding();
}
static void OrderConsumer()
{
foreach (var order in orderQueue.GetConsumingEnumerable())
{
Console.WriteLine($"Processing {order}");
Thread.Sleep(200);
}
}
static void Main()
{
Task.Run(OrderProducer);
Task.Run(OrderConsumer).Wait();
}
}
🔹 Enhancement: Implement Kafka or RabbitMQ for real-world distributed order processing.
🚀 Project 4: Parallel Image Processing System
Overview
Apply image processing filters (resize, grayscale, blur) in parallel.
Objectives
✅ Load multiple images from a folder
✅ Use Parallel.ForEach()
to apply filters
✅ Save processed images
Implementation Steps
1️⃣ Read images from a directory.
2️⃣ Apply image filters using Parallel.ForEach()
.
3️⃣ Save processed images to a new folder.
Code Example
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Threading.Tasks;
class Program
{
static void ProcessImage(string filePath)
{
using Bitmap image = new Bitmap(filePath);
string outputPath = Path.Combine("ProcessedImages", Path.GetFileName(filePath));
// Convert to grayscale
for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
Color pixel = image.GetPixel(x, y);
int gray = (pixel.R + pixel.G + pixel.B) / 3;
image.SetPixel(x, y, Color.FromArgb(gray, gray, gray));
}
}
image.Save(outputPath, ImageFormat.Jpeg);
Console.WriteLine($"Processed: {filePath}");
}
static void Main()
{
string[] files = Directory.GetFiles("C:\\Images", "*.jpg");
Parallel.ForEach(files, ProcessImage);
Console.WriteLine("All images processed.");
}
}
🔹 Enhancement: Use GPU acceleration (e.g., OpenCV) for faster processing.
🚀 Project 5: Scalable Background Job System for ASP.NET Core
Overview
Build a background task processing system using Hangfire or Worker Services.
Objectives
✅ Schedule background jobs
✅ Process jobs asynchronously
✅ Use dependency injection for services
Implementation Steps
1️⃣ Create a Worker Service in ASP.NET Core.
2️⃣ Use Task.Run()
for job execution.
3️⃣ Store job results in a database.
Code Example
using Microsoft.Extensions.Hosting;
using System;
using System.Threading;
using System.Threading.Tasks;
public class BackgroundJob : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
Console.WriteLine($"Processing job at {DateTime.Now}");
await Task.Delay(5000, stoppingToken);
}
}
}
class Program
{
static async Task Main()
{
await Host.CreateDefaultBuilder()
.ConfigureServices((_, services) => services.AddHostedService<BackgroundJob>())
.RunConsoleAsync();
}
}
🔹 Enhancement: Integrate Redis or RabbitMQ for distributed job queues.
🔥 Summary Table of Projects
Project | Key Concepts | Technologies |
---|---|---|
Web Scraper | Async/Await, Parallel Requests | HttpClient, ConcurrentBag |
File Processor | Parallel.ForEach, File I/O | Parallel Programming |
Order Processing | Producer-Consumer, Thread Safety | BlockingCollection, ThreadPool |
Image Processing | Parallel Image Manipulation | Bitmap, Parallel.ForEach |
Background Jobs | Scalable Task Processing | ASP.NET Worker Service |