Summary: in this tutorial, you’ll learn how to use the C# ManualResetEventSlim
to provide a way for threads to communicate with each other.
Introduction to the C# ManualResetEventSlim class
The ManualResetEventSlim
class allows threads to wait for a signal from another thread before continuing execution. In other words, the ManualResetEventSlim
class allows you to synchronize the execution of multiple threads.
Like an AutoResetEvent
object, a ManualResetEventSlim
object has two states:
- Signaled
- Non-signaled
The ManualResetEventSlim
class is called “Manual” because once the event is signaled, it remains signaled until you manually reset it.
Also, the ManualResetEventSlim
class is called “Slim” because it is a lightweight implementation of the ManualResetEvent
class. The ManualResetEventSlim
is optimized for performance and uses less memory than the ManualResetEvent
class.
To use the ManualResetEventSlim
class, you follow these steps:
First, create a new ManualResetEventSlim
object:
var resetEvent = new ManualResetEventSlim(false);
Code language: JavaScript (javascript)
The false
argument, which we pass the constructor, sets the initial state of the event to non-signaled.
Second, create one or more threads that wait for the event to be signaled:
var t = new Thread(() => {
// do some work
// ...
// wait for the event to be signaled
resetEvent.Wait();
// continue the execution after the event is signaled
});
Code language: JavaScript (javascript)
The Wait()
method will block the waiting threads until the event is signaled.
Third, start the thread:
t.Start();
Code language: CSS (css)
Fourth, signal the event by calling the Set()
method on the ManualResetEventSlim
object:
resetEvent.Set();
Code language: CSS (css)
The Set()
method releases all the threads that waiting on the event to resume their executions until the next Reset()
method is called on the ManualResetEventSlim
object.
Fifth, call the Reset()
method of the ManualResetEventSlim
object to reset the state to non-signaled, which blocks all the waiting threads:
resetEvent.Reset();
Code language: CSS (css)
C# ManualResetEventSlim example
The following program demonstrates how the ManualResetEventSlim
class works:
using static System.Console;
var resetEvent = new ManualResetEventSlim(false);
void DoWork()
{
WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} is waiting for the event to be signaled...");
// Wait for the event to be signaled
resetEvent.Wait();
WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} has been signaled and has resumed execution.");
}
// Create a thread that wait for the event to be signaled and start it
var t1 = new Thread(() => DoWork());
var t2 = new Thread(() => DoWork());
t1.Start();
t2.Start();
// Wait for 1s to let the thread runs for a while
Thread.Sleep(1000);
// Wait for 2s before signaling the event
WriteLine("Waiting for 2 seconds before signaling the event...");
Thread.Sleep(2000);
// Signal the event
resetEvent.Set();
// Wait for the threads to finish
t1.Join();
t2.Join();
WriteLine("Press any key to exit.");
ReadKey();
Code language: JavaScript (javascript)
Output:
Thread 10 is waiting for the event to be signaled...
Thread 11 is waiting for the event to be signaled...
Waiting for 2 seconds before signaling the event...
Thread 11 has been signaled and has resumed execution.
Thread 10 has been signaled and has resumed execution.
Press any key to exit.
Code language: PHP (php)
How it works.
First, create a new ManualResetEventSlim
object and initialize it with false
, indicating that the event is not signaled initially:
var resetEvent = new ManualResetEventSlim(false);
Code language: JavaScript (javascript)
Second, define the DoWork()
method that the waiting threads will execute:
void DoWork()
{
WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} is waiting for the event to be signaled...");
// Wait for the event to be signaled
resetEvent.Wait();
WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} has been signaled and has resumed execution.");
}
Code language: JavaScript (javascript)
The DoWork()
method writes a message to the console indicating that the thread is waiting for the event to be signaled. It then calls the Wait()
method of the ManualResetEventSLim
object to wait for the event to be signaled.
The Wait()
method blocks the threads that execute the DoWork()
method until the ManualResetEventSlim
object becomes signaled.
When the
is signaled, the method resumes its execution that writes another message to the console.ManualResetEventSlim
Third, create two threads that execute the DoWork()
method and start them immediately:
// Create threads that wait for the event to be signaled and start them
var t1 = new Thread(() => DoWork());
var t2 = new Thread(() => DoWork());
t1.Start();
t2.Start();
Code language: JavaScript (javascript)
Fourth, wait for one second to leave enough time for the threads to run until the Wait()
method is called:
Thread.Sleep(1000);
Code language: CSS (css)
Fifth, write a message to the console and wait for two seconds before signaling the event:
WriteLine("Waiting for 2 seconds before signaling the event...");
Thread.Sleep(2000);
Code language: JavaScript (javascript)
Sixth, change the state of the
object to be signaled by calling its ManualEventResetSlim
Set()
method:
// Signal the event
resetEvent.Set();
Code language: JavaScript (javascript)
After this call, the threads that execute the DoWork()
method resume their executions and display messages to the console.
Seventh, wait for the threads to complete by calling the Join()
method:
// Wait for the threads to finish
t1.Join();
t2.Join();
Code language: JavaScript (javascript)
Finally, wait for the user to press any key to exit the program:
WriteLine("Press any key to exit.");
ReadKey();
Code language: JavaScript (javascript)
Summary
- Use a C#
ManualResetEvent
class to represent a thread synchronizing event that allows one or more threads to wait for the event to occur.