AutoResetEvent 类
通知正在等待的线程已发生事件。无法继承此类。
**命名空间:**System.Threading
**程序集:**mscorlib(在 mscorlib.dll 中)
语法
声明
<ComVisibleAttribute(True)> _
Public NotInheritable Class AutoResetEvent
Inherits EventWaitHandle
用法
Dim instance As AutoResetEvent
[ComVisibleAttribute(true)]
public sealed class AutoResetEvent : EventWaitHandle
[ComVisibleAttribute(true)]
public ref class AutoResetEvent sealed : public EventWaitHandle
/** @attribute ComVisibleAttribute(true) */
public final class AutoResetEvent extends EventWaitHandle
ComVisibleAttribute(true)
public final class AutoResetEvent extends EventWaitHandle
备注
提示
应用于此类的 HostProtectionAttribute 属性 (Attribute) 具有以下 Resources 属性 (Property) 值:Synchronization | ExternalThreading。HostProtectionAttribute 不影响桌面应用程序(此类应用程序通常通过双击图标、键入命令或者在浏览器中输入 URL 来启动)。有关更多信息,请参见 HostProtectionAttribute 类或 SQL Server 编程和宿主保护属性。
在 .NET Framework 2.0 版中,AutoResetEvent 从新的 EventWaitHandle 类派生。AutoResetEvent 在功能上等效于用 EventResetMode.AutoReset 创建的 EventWaitHandle。
提示
与 AutoResetEvent 类不同的是,EventWaitHandle 类提供对已命名的系统同步事件的访问。
AutoResetEvent 允许线程通过发信号互相通信。通常,此通信涉及线程需要独占访问的资源。
线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。如果 AutoResetEvent 处于非终止状态,则该线程阻塞,并等待当前控制资源的线程通过调用 Set 发出资源可用的信号。
调用 Set 向 AutoResetEvent 发信号以释放等待线程。AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。如果没有任何线程在等待,则状态将无限期地保持为终止状态。
可以通过将一个布尔值传递给构造函数来控制 AutoResetEvent 的初始状态,如果初始状态为终止状态,则为 true;否则为 false。
AutoResetEvent 也可以同 staticWaitAll 和 WaitAny 方法一起使用。
有关线程同步机制的更多信息,请参见概念文档中的 AutoResetEvent。
示例
下面的代码示例阐释了如何使用等待句柄来发送复杂数字计算的不同阶段的完成信号。此计算的格式为:result = first term + second term + third term,其中每项都要求使用计算出的基数进行预计算和最终计算。
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() );
}
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.AutoResetEvent
线程安全
此类是线程安全的。
平台
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
.NET Framework 并不是对每个平台的所有版本都提供支持。有关受支持版本的列表,请参见系统要求。
版本信息
.NET Framework
受以下版本支持:2.0、1.1、1.0
.NET Compact Framework
受以下版本支持:2.0、1.0
请参见
参考
AutoResetEvent 成员
System.Threading 命名空间
WaitHandle