The Wait () and Pulse () mechanisms are used for inter-thread interaction. When using the Wait () method on an object, the thread accessing the object waits until it is awakened. The Pulse () and PulseAll () methods are used to notify the waiting thread
to wake up. Here's an example of how the Wait () and Pulse () methods work
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace WaitAndPulse
{
public class LockMe
{
}
class WaitPulse1
{
private int result = 0;
private LockMe lM;
public WaitPulse1()
{
}
public WaitPulse1(LockMe l)
{
this.lM = l;
}
public void CriticalSection()
{
Monitor.Enter(this.lM);
//Enter the Critical Section
Console.WriteLine("WaitPulse1: Entered Thread "
+ Thread.CurrentThread.GetHashCode());
for (int i = 1; i <= 5; i++)
{
Monitor.Wait(this.lM);
Console.WriteLine("WaitPulse1: WokeUp");
Console.WriteLine("WaitPulse1: Result = "
+ result++
+ " ThreadID "
+ Thread.CurrentThread.GetHashCode());
Monitor.Pulse(this.lM);
}
Console.WriteLine("WaitPulse1: Exiting Thread "
+ Thread.CurrentThread.GetHashCode());
//Exit the Critical Section
Monitor.Exit(this.lM);
}
}
class WaitPulse2
{
private int result = 0;
private LockMe lM;
public WaitPulse2()
{
}
public WaitPulse2(LockMe l)
{
this.lM = l;
}
public void CriticalSection()
{
Monitor.Enter(this.lM);
//Enter the Critical Section
Console.WriteLine("WaitPulse2: Entered Thread "
+ Thread.CurrentThread.GetHashCode());
for (int i = 1; i <= 5; i++)
{
Monitor.Pulse(this.lM);
Console.WriteLine("WaitPulse2: Result = "
+ result++
+ " ThreadID "
+ Thread.CurrentThread.GetHashCode());
Monitor.Wait(this.lM);
Console.WriteLine("WaitPulse2: WokeUp");
}
Console.WriteLine("WaitPulse2: Exiting Thread "
+ Thread.CurrentThread.GetHashCode());
//Exit the Critical Section
Monitor.Exit(this.lM);
}
}
public class ClassForMain
{
public static void Main(string[] args)
{
LockMe l = new LockMe();
WaitPulse1 e1 = new WaitPulse1(l);
WaitPulse2 e2 = new WaitPulse2(l);
Thread t1 = new Thread(new ThreadStart(e1.CriticalSection));
t1.Start();
Thread t2 = new Thread(new ThreadStart(e2.CriticalSection));
t2.Start();
//Wait till the user enters something
Console.ReadLine();
}
}
}
In the Main () method, we created a LockMe object. Then create two objects, WaitPulse1, WaitPulse2, and then delegate them to the thread so that the thread can call the CriticalSection () method of both objects. Note that the LockMe instances in the two
objects WaitPulse1 and WaitPulse2 are different because the object reference passed to the corresponding constructor is different. After initializing the object, we create two threads, t1 and t2, and pass the respective CriticalSection () function to each
of these two threads.
Assuming WaitPulse1.CriticalSection () executes first, thread t1 enters the key part of the method and executes Monitor.Wait () in the for loop after locking the LockMe object. Due to the implementation of Monitor.Wait (), it has to wait for other threads
to call the Monitor.Pulse () method (a runtime notification) to wake it up. We lock the LockMe object because we only want to have access to the shared LockMe instance for just one object at any one time.
Note When a thread executes the Monitor.Wait () method, it temporarily releases the lock on the LockMe object so that other threads can access the LockMe object. After the thread t1 enters the wait state, the thread t2 can freely access the LockMe object.
Although both threads have their own LockMe objects (WaitPulse1, WaitPulse2), they both reference the same object. Thread t2 gets the lock on the LockMe object and enters the WaitPulse2.CriticalSection () method. When it enters the for loop, it sends a run-time
notification (Monitor.Pulse ()) to the thread waiting for the LockMe object (t1 in this case) and enters the wait state.
Finally, t1 wakes up and gets LockMe lock. Thread t1 then accesses the result variable and sends a runtime notification to the thread waiting for the LockMe object (t2 in this case). So repeatedly until the for loop ends.
You also coudl refer to the article below for full understanding:
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue.
If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.
Member
68 Points
240 Posts
Monitor.Wait/Monitor.Pulse
Jan 31, 2018 07:42 PM|vinodkpasi|LINK
Can anyone explain Monitor.Wait/Monitor.Pulse with simple example?
Star
8670 Points
2882 Posts
Re: Monitor.Wait/Monitor.Pulse
Feb 01, 2018 03:13 AM|Cathy Zou|LINK
Hi vinodkpasi
The Wait () and Pulse () mechanisms are used for inter-thread interaction. When using the Wait () method on an object, the thread accessing the object waits until it is awakened. The Pulse () and PulseAll () methods are used to notify the waiting thread to wake up. Here's an example of how the Wait () and Pulse () methods work
In the Main () method, we created a LockMe object. Then create two objects, WaitPulse1, WaitPulse2, and then delegate them to the thread so that the thread can call the CriticalSection () method of both objects. Note that the LockMe instances in the two objects WaitPulse1 and WaitPulse2 are different because the object reference passed to the corresponding constructor is different. After initializing the object, we create two threads, t1 and t2, and pass the respective CriticalSection () function to each of these two threads.
Assuming WaitPulse1.CriticalSection () executes first, thread t1 enters the key part of the method and executes Monitor.Wait () in the for loop after locking the LockMe object. Due to the implementation of Monitor.Wait (), it has to wait for other threads to call the Monitor.Pulse () method (a runtime notification) to wake it up. We lock the LockMe object because we only want to have access to the shared LockMe instance for just one object at any one time.
Note When a thread executes the Monitor.Wait () method, it temporarily releases the lock on the LockMe object so that other threads can access the LockMe object. After the thread t1 enters the wait state, the thread t2 can freely access the LockMe object. Although both threads have their own LockMe objects (WaitPulse1, WaitPulse2), they both reference the same object. Thread t2 gets the lock on the LockMe object and enters the WaitPulse2.CriticalSection () method. When it enters the for loop, it sends a run-time notification (Monitor.Pulse ()) to the thread waiting for the LockMe object (t1 in this case) and enters the wait state.
Finally, t1 wakes up and gets LockMe lock. Thread t1 then accesses the result variable and sends a runtime notification to the thread waiting for the LockMe object (t2 in this case). So repeatedly until the for loop ends.
You also coudl refer to the article below for full understanding:
http://www.c-sharpcorner.com/UploadFile/1d42da/wait-and-pulse-method-in-threading-C-Sharp/
Best regards
Cathy
Please remember to click "Mark as Answer" the responses that resolved your issue.
If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.