A repository of exercises to support the training.
In this module, you will learn how to utilize parallel programming to improve performance in C#. You'll explore the benefits of parallel execution and identify common challenges such as race conditions, as well as techniques to mitigate these issues.
Imagine you are building a futuristic city simulation where various systems (like transportation, energy, and infrastructure) need to update shared counters concurrently. Understanding the challenges of shared resource access in a parallelized context will help you design robust solutions.
Instructions:
Understand the Problem: When multiple threads or tasks modify a shared resource, a race condition can occur, leading to unpredictable results.
Explore the Issue:
Mitigate the Issue:
Interlocked to safely update the shared resource.using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
    static void Main(string[] args)
    {
        // Shared counter variable
        int sharedCounter = 0;
        // Simulating parallel tasks with race condition
        Parallel.For(0, 1000, i =>
        {
            // Uncomment the next line to observe the race condition
            // sharedCounter++;
            // Thread-safe increment using Interlocked
            Interlocked.Increment(ref sharedCounter);
        });
        Console.WriteLine($"Final Counter Value: {sharedCounter}");
        // The result with Interlocked will be 1000. Without it, it might be less due to race conditions.
    }
}
Expected Outcome: Learners will understand the concept of race conditions and why they occur. They will successfully mitigate race conditions using thread-safe constructs like Interlocked.
Next Steps: Extend the program to explore other thread-safety mechanisms such as lock or Monitor. Implement additional scenarios where shared resources need to be protected, like maintaining a collection of log entries or managing a producer-consumer queue.
Happy experimenting.