Information
The topic you requested is included in another documentation set. For convenience, it's displayed below. Choose Switch to see the topic in its original location.

ManualResetEvent Class

Notifies one or more waiting threads that an event has occurred. This class cannot be inherited.

For a list of all members of this type, see ManualResetEvent Members.

System.Object
   System.MarshalByRefObject
      System.Threading.WaitHandle
         System.Threading.ManualResetEvent

[Visual Basic]
NotInheritable Public Class ManualResetEvent
   Inherits WaitHandle
[C#]
public sealed class ManualResetEvent : WaitHandle
[C++]
public __gc __sealed class ManualResetEvent : public WaitHandle
[JScript]
public class ManualResetEvent extends WaitHandle

Thread Safety

This type is safe for multithreaded operations.

Remarks

ManualResetEvent allows threads to communicate with each other by signaling. Typically, this communication concerns a task which one thread must complete before other threads can proceed.

When a thread begins an activity that must complete before other threads proceed, it calls Reset to put ManualResetEvent in the nonsignaled state. This thread can be thought of as controlling the ManualResetEvent. Threads that call WaitOne on the ManualResetEvent will block, awaiting the signal. When the controlling thread completes the activity, it calls Set to signal that the waiting threads can proceed. All waiting threads are released.

Once it has been signaled, ManualResetEvent remains signaled until it is manually reset. That is, calls to WaitOne return immediately.

You can control the initial state of a ManualResetEvent by passing a Boolean value to the constructor, true if the initial state is signaled and false otherwise.

ManualResetEvent can also be used with the static (Shared in Visual Basic) WaitAll and WaitAny methods.

For more information about thread synchronization mechanisms, see ManualResetEvent in the conceptual documentation.

Example

[Visual Basic, C#, C++] The following code example demonstrates how to use wait handles to signal the completion of various stages of a complicated number calculation. The calculation is of the form: result = first term + second

term + third term, where each term requires a precalculation and a final calculation using a calculated base number.

[Visual Basic] 
Imports System
Imports System.Threading

Public Class CalculateTest

    <MTAThreadAttribute> _
    Shared Sub Main()
        Dim calc As New Calculate()
        Console.WriteLine("Result = {0}.", _
            calc.Result(234).ToString())
        Console.WriteLine("Result = {0}.", _
            calc.Result(55).ToString())
    End Sub
End Class

Public Class Calculate

    Dim baseNumber, firstTerm, secondTerm, thirdTerm As Double
    Dim autoEvents() As AutoResetEvent
    Dim manualEvent As ManualResetEvent

    ' Generate random numbers to simulate the actual calculations.
    Dim randomGenerator As Random 

    Sub New()
        autoEvents = New AutoResetEvent(2) { _
            New AutoResetEvent(False), _
            New AutoResetEvent(False), _
            New AutoResetEvent(False) }

        manualEvent = New ManualResetEvent(False)
    End Sub

    Private Sub CalculateBase(stateInfo As Object)
        baseNumber = randomGenerator.NextDouble()

        ' Signal that baseNumber is ready.
        manualEvent.Set()
    End Sub

    ' The following CalculateX methods all perform the same
    ' series of steps as commented in CalculateFirstTerm.

    Private Sub CalculateFirstTerm(stateInfo As Object)
    
        ' Perform a precalculation.
        Dim preCalc As Double = randomGenerator.NextDouble()

        ' Wait for baseNumber to be calculated.
        manualEvent.WaitOne()

        ' Calculate the first term from preCalc and baseNumber.
        firstTerm = preCalc * baseNumber * _
            randomGenerator.NextDouble()

        ' Signal that the calculation is finished.
        autoEvents(0).Set()
    End Sub

    Private Sub CalculateSecondTerm(stateInfo As Object)
        Dim preCalc As Double = randomGenerator.NextDouble()
        manualEvent.WaitOne()
        secondTerm = preCalc * baseNumber * _
            randomGenerator.NextDouble()
        autoEvents(1).Set()
    End Sub

    Private Sub CalculateThirdTerm(stateInfo As Object)
        Dim preCalc As Double = randomGenerator.NextDouble()
        manualEvent.WaitOne()
        thirdTerm = preCalc * baseNumber * _
            randomGenerator.NextDouble()
        autoEvents(2).Set()
    End Sub

    Function Result(seed As Integer) As Double

        randomGenerator = New Random(seed)

        ' Simultaneously calculate the terms.
        ThreadPool.QueueUserWorkItem(AddressOf CalculateBase)
        ThreadPool.QueueUserWorkItem(AddressOf CalculateFirstTerm)
        ThreadPool.QueueUserWorkItem(AddressOf CalculateSecondTerm)
        ThreadPool.QueueUserWorkItem(AddressOf CalculateThirdTerm)

        ' Wait for all of the terms to be calculated.
        WaitHandle.WaitAll(autoEvents)

        ' Reset the wait handle for the next calculation.
        manualEvent.Reset()

        Return firstTerm + secondTerm + thirdTerm
    End Function

End Class

[C#] 
using System;
using System.Threading;

class CalculateTest
{
    static void Main()
    {
        Calculate calc = new Calculate();
        Console.WriteLine("Result = {0}.", 
            calc.Result(234).ToString());
        Console.WriteLine("Result = {0}.", 
            calc.Result(55).ToString());
    }
}

class Calculate
{
    double baseNumber, firstTerm, secondTerm, thirdTerm;
    AutoResetEvent[] autoEvents;
    ManualResetEvent manualEvent;

    // Generate random numbers to simulate the actual calculations.
    Random randomGenerator;

    public Calculate()
    {
        autoEvents = new AutoResetEvent[]
        {
            new AutoResetEvent(false),
            new AutoResetEvent(false),
            new AutoResetEvent(false)
        };

        manualEvent = new ManualResetEvent(false);
    }

    void CalculateBase(object stateInfo)
    {
        baseNumber = randomGenerator.NextDouble();

        // Signal that baseNumber is ready.
        manualEvent.Set();
    }

    // The following CalculateX methods all perform the same
    // series of steps as commented in CalculateFirstTerm.

    void CalculateFirstTerm(object stateInfo)
    {
        // Perform a precalculation.
        double preCalc = randomGenerator.NextDouble();

        // Wait for baseNumber to be calculated.
        manualEvent.WaitOne();

        // Calculate the first term from preCalc and baseNumber.
        firstTerm = preCalc * baseNumber * 
            randomGenerator.NextDouble();

        // Signal that the calculation is finished.
        autoEvents[0].Set();
    }

    void CalculateSecondTerm(object stateInfo)
    {
        double preCalc = randomGenerator.NextDouble();
        manualEvent.WaitOne();
        secondTerm = preCalc * baseNumber * 
            randomGenerator.NextDouble();
        autoEvents[1].Set();
    }

    void CalculateThirdTerm(object stateInfo)
    {
        double preCalc = randomGenerator.NextDouble();
        manualEvent.WaitOne();
        thirdTerm = preCalc * baseNumber * 
            randomGenerator.NextDouble();
        autoEvents[2].Set();
    }

    public double Result(int seed)
    {
        randomGenerator = new Random(seed);

        // Simultaneously calculate the terms.
        ThreadPool.QueueUserWorkItem(
            new WaitCallback(CalculateBase));
        ThreadPool.QueueUserWorkItem(
            new WaitCallback(CalculateFirstTerm));
        ThreadPool.QueueUserWorkItem(
            new WaitCallback(CalculateSecondTerm));
        ThreadPool.QueueUserWorkItem(
            new WaitCallback(CalculateThirdTerm));

        // Wait for all of the terms to be calculated.
        WaitHandle.WaitAll(autoEvents);

        // Reset the wait handle for the next calculation.
        manualEvent.Reset();

        return firstTerm + secondTerm + thirdTerm;
    }
}

[C++] 
#using <mscorlib.dll>
using namespace System;
using namespace System::Threading;

__gc class Calculate
{
    double baseNumber, firstTerm, secondTerm, thirdTerm;
    AutoResetEvent* autoEvents __gc [];
    ManualResetEvent* manualEvent;

    // Generate random numbers to simulate the actual calculations.
    Random* randomGenerator;

public:
    Calculate()
    {
        autoEvents = new AutoResetEvent* __gc [3];
        autoEvents[0] = new AutoResetEvent(false);
        autoEvents[1] = new AutoResetEvent(false);
        autoEvents[2] = new AutoResetEvent(false);

        manualEvent = new ManualResetEvent(false);
    }

private:
    void CalculateBase(Object* stateInfo)
    {
        baseNumber = randomGenerator->NextDouble();

        // Signal that baseNumber is ready.
        manualEvent->Set();
    }

    // The following CalculateX methods all perform the same
    // series of steps as commented in CalculateFirstTerm.

    void CalculateFirstTerm(Object* stateInfo)
    {
        // Perform a precalculation.
        double preCalc = randomGenerator->NextDouble();

        // Wait for baseNumber to be calculated.
        manualEvent->WaitOne();

        // Calculate the first term from preCalc and baseNumber.
        firstTerm = preCalc * baseNumber * 
            randomGenerator->NextDouble();

        // Signal that the calculation is finished.
        autoEvents[0]->Set();
    }

    void CalculateSecondTerm(Object* stateInfo)
    {
        double preCalc = randomGenerator->NextDouble();
        manualEvent->WaitOne();
        secondTerm = preCalc * baseNumber * 
            randomGenerator->NextDouble();
        autoEvents[1]->Set();
    }

    void CalculateThirdTerm(Object* stateInfo)
    {
        double preCalc = randomGenerator->NextDouble();
        manualEvent->WaitOne();
        thirdTerm = preCalc * baseNumber * 
            randomGenerator->NextDouble();
        autoEvents[2]->Set();
    }

public:
    double Result(int seed)
    {
        randomGenerator = new Random(seed);

        // Simultaneously calculate the terms.
        ThreadPool::QueueUserWorkItem(
            new WaitCallback(this, &Calculate::CalculateBase));
        ThreadPool::QueueUserWorkItem(
            new WaitCallback(this, &Calculate::CalculateFirstTerm));
        ThreadPool::QueueUserWorkItem(
            new WaitCallback(this, &Calculate::CalculateSecondTerm));
        ThreadPool::QueueUserWorkItem(
            new WaitCallback(this, &Calculate::CalculateThirdTerm));

        // Wait for all of the terms to be calculated.
        WaitHandle::WaitAll(autoEvents);

        // Reset the wait handle for the next calculation.
        manualEvent->Reset();

        return firstTerm + secondTerm + thirdTerm;
    }
};

void main()
{
    Calculate* calc = new Calculate();
    Console::WriteLine(S"Result = {0}.", 
        calc->Result(234).ToString());
    Console::WriteLine(S"Result = {0}.", 
        calc->Result(55).ToString());
}

[JScript] No example is available for JScript. To view a Visual Basic, C#, or C++ example, click the Language Filter button Language Filter in the upper-left corner of the page.

Requirements

Namespace: System.Threading

Platforms: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 family, .NET Compact Framework

Assembly: Mscorlib (in Mscorlib.dll)

See Also

ManualResetEvent Members | System.Threading Namespace | Threading | ManualResetEvent

Show:
© 2014 Microsoft