Export (0) Print
Expand All
3 out of 9 rated this helpful - Rate this topic

ManualResetEvent Class

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

Namespace: System.Threading
Assembly: mscorlib (in mscorlib.dll)

[ComVisibleAttribute(true)] 
public sealed class ManualResetEvent : EventWaitHandle
/** @attribute ComVisibleAttribute(true) */ 
public final class ManualResetEvent extends EventWaitHandle
ComVisibleAttribute(true) 
public final class ManualResetEvent extends EventWaitHandle
NoteNote

The HostProtectionAttribute attribute applied to this class has the following Resources property value: Synchronization | ExternalThreading. The HostProtectionAttribute does not affect desktop applications (which are typically started by double-clicking an icon, typing a command, or entering a URL in a browser). For more information, see the HostProtectionAttribute class or SQL Server Programming and Host Protection Attributes.

In the .NET Framework version 2.0, ManualResetEvent derives from the new EventWaitHandle class. A ManualResetEvent is functionally equivalent to an EventWaitHandle created with EventResetMode.ManualReset.

NoteNote

Unlike the ManualResetEvent class, the EventWaitHandle class provides access to named system synchronization events.

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 non-signaled 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 staticWaitAll and WaitAny methods.

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

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.

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;
    }
}

import System.*;
import System.Threading.*;

class CalculateTest
{
    public static void main(String[] args)
    {
        Calculate calc = new Calculate();
        Console.WriteLine("Result = {0}.", String.valueOf(calc.Result(234)));
        Console.WriteLine("Result = {0}.", String.valueOf(calc.Result(55)));
    } //main
} //CalculateTest

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

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

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

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

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

    // 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();
    } //CalculateFirstTerm

    void CalculateSecondTerm(Object stateInfo)
    {
        double preCalc = randomGenerator.NextDouble();

        manualEvent.WaitOne();
        secondTerm = preCalc * baseNumber * randomGenerator.NextDouble();
        autoEvents[1].Set();
    } //CalculateSecondTerm

    void CalculateThirdTerm(Object stateInfo)
    {
        double preCalc = randomGenerator.NextDouble();

        manualEvent.WaitOne();
        thirdTerm = preCalc * baseNumber * randomGenerator.NextDouble();
        autoEvents[2].Set();
    } //CalculateThirdTerm

    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;
    } //Result
} //Calculate

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

This class is thread safe.

Windows 98, Windows 2000 SP4, Windows CE, Windows Millennium Edition, Windows Mobile for Pocket PC, Windows Mobile for Smartphone, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see System Requirements.

.NET Framework

Supported in: 2.0, 1.1, 1.0

.NET Compact Framework

Supported in: 2.0, 1.0

Community Additions

ADD
Show:
© 2014 Microsoft. All rights reserved.