Notifies a waiting thread that an event has occurred. This class cannot be inherited.
Namespace:
System.Threading
Assembly:
mscorlib (in mscorlib.dll)
Visual Basic (Declaration)
<ComVisibleAttribute(True)> _
<HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization := True, _
ExternalThreading := True)> _
Public NotInheritable Class AutoResetEvent _
Inherits EventWaitHandle
Dim instance As AutoResetEvent
[ComVisibleAttribute(true)]
[HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true,
ExternalThreading = true)]
public sealed class AutoResetEvent : EventWaitHandle
[ComVisibleAttribute(true)]
[HostProtectionAttribute(SecurityAction::LinkDemand, Synchronization = true,
ExternalThreading = true)]
public ref class AutoResetEvent sealed : public EventWaitHandle
public final class AutoResetEvent extends EventWaitHandle
In the .NET Framework version 2.0, AutoResetEvent derives from the new EventWaitHandle class. An AutoResetEvent is functionally equivalent to an EventWaitHandle created with EventResetMode..::.AutoReset.
Note: |
|---|
Unlike the AutoResetEvent class, the EventWaitHandle class provides access to named system synchronization events. |
AutoResetEvent allows threads to communicate with each other by signaling. Typically, this communication concerns a resource to which threads need exclusive access.
A thread waits for a signal by calling WaitOne on the AutoResetEvent. If the AutoResetEvent is in the non-signaled state, the thread blocks, waiting for the thread that currently controls the resource to signal that the resource is available by calling Set.
Calling Set signals AutoResetEvent to release a waiting thread. AutoResetEvent remains signaled until a single waiting thread is released, and then automatically returns to the non-signaled state. If no threads are waiting, the state remains signaled indefinitely.
If a thread calls WaitOne while the AutoResetEvent is in the signaled state, the thread does not block. The AutoResetEvent releases the thread immediately and returns to the non-signaled state.
Important Note: |
|---|
There is no guarantee that every call to the Set method will release a thread. If two calls are too close together, so that the second call occurs before a thread has been released, only one thread is released. It is as if the second call did not happen. Also, if Set is called when there are no threads waiting and the AutoResetEvent is already signaled, the call has no effect. |
You can control the initial state of an AutoResetEvent by passing a Boolean value to the constructor, true if the initial state is signaled and false otherwise.
AutoResetEvent can also be used with the static WaitAll and WaitAny methods.
For more information about thread synchronization mechanisms, see AutoResetEvent 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.
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
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;
}
}
using namespace System;
using namespace System::Threading;
ref class Calculate
{
private:
double baseNumber;
double firstTerm;
double secondTerm;
double thirdTerm;
array<AutoResetEvent^>^autoEvents;
ManualResetEvent^ manualEvent;
// Generate random numbers to simulate the actual calculations.
Random^ randomGenerator;
public:
Calculate()
{
autoEvents = gcnew array<AutoResetEvent^>(3);
autoEvents[ 0 ] = gcnew AutoResetEvent( false );
autoEvents[ 1 ] = gcnew AutoResetEvent( false );
autoEvents[ 2 ] = gcnew AutoResetEvent( false );
manualEvent = gcnew 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 = gcnew Random( seed );
// Simultaneously calculate the terms.
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( this, &Calculate::CalculateBase ) );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( this, &Calculate::CalculateFirstTerm ) );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( this, &Calculate::CalculateSecondTerm ) );
ThreadPool::QueueUserWorkItem( gcnew 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;
}
};
int main()
{
Calculate^ calc = gcnew Calculate;
Console::WriteLine( "Result = {0}.", calc->Result( 234 ).ToString() );
Console::WriteLine( "Result = {0}.", calc->Result( 55 ).ToString() );
}
System..::.Object
System..::.MarshalByRefObject
System.Threading..::.WaitHandle
System.Threading..::.EventWaitHandle
System.Threading..::.AutoResetEvent
This class is thread safe.
Windows 7, Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98, Windows CE, Windows Mobile for Smartphone, Windows Mobile for Pocket PC, Xbox 360, Zune
The .NET Framework and .NET Compact Framework do not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.
.NET Framework
Supported in: 3.5, 3.0, 2.0, 1.1, 1.0
.NET Compact Framework
Supported in: 3.5, 2.0, 1.0
XNA Framework
Supported in: 3.0, 2.0, 1.0
Reference
Other Resources