Tech Solution Stack

Tech Solution Stack – Tech Solution Stack is a blog sharing practical guide and tutorials on modern tech solutions for developers.

ads header

Thursday, August 21, 2025

.NET Thread Synchronization – Monitor.Wait & Monitor.Pulse Walkthrough

 Introduction

When we build applications in .NET, we often need to run multiple tasks at the same time using threads. But when more than one thread tries to access the same resource (like a file, variable, or database), it can cause confusion or errors if not properly handled. This situation is called a thread synchronization problem.

In .NET, there are several thread synchronization techniques.Lets discuss about Wait and Pulse method from Monitor class.

1.One way signaling

In this problem statement we will deal with one way signaling.

Taking a use case from Building Automation System and its implementation using Monitor.wait and pulse.This is just a simple solution,where in real-time there are better solutions are available looking at the need,which we will take in upcoming posts.

Use case 1

  • In a Building Automation System (BAS), an Air Conditioning (AC) controller should automatically respond to temperature changes reported by a sensor.
  • The sensor continuously monitors the room temperature.
  • If the temperature goes above 26°C, the sensor should signal the AC controller to turn ON the AC.
  • If the temperature falls below 23°C, the sensor should signal the AC controller to turn OFF the AC.
  • The AC controller should only act when it receives a signal from the sensor, not on its own.

This ensures that the AC runs only when needed, thereby saving power.



Solution

We use the .NET Monitor class for signaling between the Temperature Sensor and the AC Controller.

Step 1 Sensor signals to Controller

  • Condition: temperature > 26°C
  • Action: Temperature sensor calls Monitor.Pulse to notify the controller.

Step 2 Controller turns AC ON and waits

  • Controller wakes up, turns ON the AC, then calls Monitor.Wait to wait for the next signal.

Step 3 Sensor signals to turn OFF

  • Condition: temperature < 23°C
  • Action: Sensor calls Monitor.Pulse again to notify the controller.

Step 4 Controller turns AC OFF and waits

  • Controller wakes up, turns OFF the AC, then calls Monitor.Wait to wait for the next signal.

This one-way signaling ensures the controller acts only when needed, reducing CPU work and saving power.

C# Code sample

using System;
using System.Threading;

class Program
{
    static object locker = new object();
    static bool tooHot = false;  // Shared state
    static bool newSignal = false; // To avoid repeated wake-ups

    static void Main(string[] args)
    {
        Thread sensorThread = new Thread(SensorThread);
        Thread acThread = new Thread(ACControllerThread);

        sensorThread.Start();
        acThread.Start();

        sensorThread.Join();
        acThread.Join();
    }

    static void SensorThread()
    {
        Random rnd = new Random();

        while (true)
        {
            int currentTemp = rnd.Next(20, 30); // simulate sensor readings
            Console.WriteLine($"\n[Sensor] Current Temperature = {currentTemp}°C");

            lock (locker)
            {
                if (currentTemp > 26)
                {
                    tooHot = true;
                    newSignal = true;
                    Console.WriteLine("[Sensor] Too hot! Notify AC controller...");
                    Monitor.Pulse(locker);
                }
                else if (currentTemp < 23)
                {
                    tooHot = false;
                    newSignal = true;
                    Console.WriteLine("[Sensor] Cool enough! Notify AC controller...");
                    Monitor.Pulse(locker);
                }
            }

            Thread.Sleep(2000); // wait before next reading
        }
    }

    static void ACControllerThread()
    {
        bool acOn = false;

        while (true)
        {
            lock (locker)
            {
                while (!newSignal)
                    Monitor.Wait(locker);  // wait until sensor signals

                newSignal = false; // reset after handling

                if (tooHot && !acOn)
                {
                    Console.WriteLine("[AC] Turning ON Air Conditioning!");
                    acOn = true;
                }
                else if (!tooHot && acOn)
                {
                    Console.WriteLine("[AC] Turning OFF Air Conditioning!");
                    acOn = false;
                }
                else
                {
                    Console.WriteLine("[AC] No action needed.");
                }
            }
        }
    }
}
Expected Sample Output

[Sensor] Current Temperature = 28°C
[Sensor] Too hot! Notify AC controller...
[AC] Turning ON Air Conditioning!

[Sensor] Current Temperature = 24°C
(no signal, within range)

[Sensor] Current Temperature = 21°C
[Sensor] Cool enough! Notify AC controller...
[AC] Turning OFF Air Conditioning!

Conclusion

Understanding Monitor.Wait and Monitor.Pulse is crucial when working with multithreaded applications in .NET. They provide a reliable way to synchronize threads, ensuring that shared resources are accessed in a controlled manner. While Monitor.Wait pauses a thread until it receives a signal, Monitor.Pulse (or PulseAll) wakes up waiting threads to continue execution. Together, they form a powerful mechanism for building producer-consumer patterns, task scheduling systems, and other coordination-based solutions.
However, with great power comes the responsibility of using them correctly—misusing these methods can easily lead to deadlocks or unexpected behavior. By carefully designing thread communication and combining these synchronization techniques with good coding practices, developers can build efficient, responsive, and thread-safe .NET applications.

No comments:

Post a Comment

Powered by Blogger.

Subscribe by Email

Search This Blog

Post Top Ad

ad728