ref: https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.eventwaithandle?view=net-5.0
定义
表示一个线程同步事件。
public class EventWaitHandle : System.Threading.WaitHandle
- 继承
- 派生
示例
下面的代码示例使用 SignalAndWait(WaitHandle, WaitHandle) 方法重载,以允许主线程向阻止的线程发出信号,并等待线程完成任务。
该示例启动五个线程,并允许它们阻止 EventWaitHandle 使用标志创建的 EventResetMode.AutoReset ,然后在每次用户按 ENTER 键时释放一个线程。 然后,该示例将另一线程排队,并通过使用标志创建的所有线程释放它们 EventWaitHandle EventResetMode.ManualReset 。
using System;
using System.Threading;
public class Example
{
// The EventWaitHandle used to demonstrate the difference
// between AutoReset and ManualReset synchronization events.
//
private static EventWaitHandle ewh;
// A counter to make sure all threads are started and
// blocked before any are released. A Long is used to show
// the use of the 64-bit Interlocked methods.
//
private static long threadCount = 0;
// An AutoReset event that allows the main thread to block
// until an exiting thread has decremented the count.
//
private static EventWaitHandle clearCount =
new EventWaitHandle(false, EventResetMode.AutoReset);
[MTAThread]
public static void Main()
{
// Create an AutoReset EventWaitHandle.
//
ewh = new EventWaitHandle(false, EventResetMode.AutoReset);
// Create and start five numbered threads. Use the
// ParameterizedThreadStart delegate, so the thread
// number can be passed as an argument to the Start
// method.
for (int i = 0; i <= 4; i++)
{
Thread t = new Thread(
new ParameterizedThreadStart(ThreadProc)
);
t.Start(i);
}
// Wait until all the threads have started and blocked.
// When multiple threads use a 64-bit value on a 32-bit
// system, you must access the value through the
// Interlocked class to guarantee thread safety.
//
while (Interlocked.Read(ref threadCount) < 5)
{
Thread.Sleep(500);
}
// Release one thread each time the user presses ENTER,
// until all threads have been released.
//
while (Interlocked.Read(ref threadCount) > 0)
{
Console.WriteLine("Press ENTER to release a waiting thread.");
Console.ReadLine();
// SignalAndWait signals the EventWaitHandle, which
// releases exactly one thread before resetting,
// because it was created with AutoReset mode.
// SignalAndWait then blocks on clearCount, to
// allow the signaled thread to decrement the count
// before looping again.
//
WaitHandle.SignalAndWait(ewh, clearCount);
}
Console.WriteLine();
// Create a ManualReset EventWaitHandle.
//
ewh = new EventWaitHandle(false, EventResetMode.ManualReset);
// Create and start five more numbered threads.
//
for(int i=0; i<=4; i++)
{
Thread t = new Thread(
new ParameterizedThreadStart(ThreadProc)
);
t.Start(i);
}
// Wait until all the threads have started and blocked.
//
while (Interlocked.Read(ref threadCount) < 5)
{
Thread.Sleep(500);
}
// Because the EventWaitHandle was created with
// ManualReset mode, signaling it releases all the
// waiting threads.
//
Console.WriteLine("Press ENTER to release the waiting threads.");
Console.ReadLine();
ewh.Set();
}
public static void ThreadProc(object data)
{
int index = (int) data;
Console.WriteLine("Thread {0} blocks.", data);
// Increment the count of blocked threads.
Interlocked.Increment(ref threadCount);
// Wait on the EventWaitHandle.
ewh.WaitOne();
Console.WriteLine("Thread {0} exits.", data);
// Decrement the count of blocked threads.
Interlocked.Decrement(ref threadCount);
// After signaling ewh, the main thread blocks on
// clearCount until the signaled thread has
// decremented the count. Signal it now.
//
clearCount.Set();
}
}
注解
EventWaitHandle类允许线程通过发出信号互相通信。 通常,一个或多个线程会在上阻塞 EventWaitHandle ,直到被阻止的线程调用 Set 方法,释放一个或多个被阻止的线程。 线程可以 EventWaitHandle 通过调用 static
Shared
Visual Basic) 方法中的 (向发出信号,然后在其上进行阻止 WaitHandle.SignalAndWait 。
备注
EventWaitHandle类提供对已命名的系统同步事件的访问。
已发出信号的的行为 EventWaitHandle 取决于其重置模式。 EventWaitHandle使用标志创建的 EventResetMode.AutoReset 时,在释放单个等待线程后,将自动重置。 在 Reset 方法获得调用前,一直向使用 EventResetMode.ManualReset 标志创建的 EventWaitHandle 发出信号。
自动重置事件提供对资源的独占访问权限。 如果向自动重置事件发出信号时没有线程正在等待,此信号会一直发出到有线程尝试在等待句柄上等待。 此时,事件会释放相应线程并立即重置自身,同时阻止后续线程。
手动重置事件与入口类似。 如果事件未发出信号,则等待它的线程将会阻止。 当事件收到信号时,将释放所有正在等待的线程,并且事件将保持发出信号 (即,后续等待不会阻止) ,直到 Reset 调用其方法。 如果一个线程必须完成某个活动,然后其他线程才能继续,则手动重置事件很有用。
EventWaitHandle 对象可以与 static
Shared
Visual Basic) 和方法中的 (一起使用 WaitHandle.WaitAll WaitHandle.WaitAny 。
有关详细信息,请参阅同步基元概述一文中的 "线程交互" 或 "信号" 部分。
构造函数
EventWaitHandle(Boolean, EventResetMode) |
初始化 EventWaitHandle 类的新实例,并指定等待句柄最初是否处于终止状态,以及它是自动重置还是手动重置。 |
EventWaitHandle(Boolean, EventResetMode, String) |
初始化 EventWaitHandle 类的新实例,并指定在此调用后创建的等待句柄最初是否处于终止状态,它是自动重置还是手动重置,以及系统同步事件的名称。 |
EventWaitHandle(Boolean, EventResetMode, String, Boolean) |
初始化 EventWaitHandle 类的新实例,指定如果将等待句柄作为此调用的结果而创建,最初是否通过信号通知此句柄;指定是否自动或手动重置系统同步事件的名称,以及一个布尔变量,在调用后其值指示是否创建了命名的系统事件。 |
字段
WaitTimeout |
指示在任何等待句柄终止之前 WaitAny(WaitHandle[], Int32, Boolean) 操作已超时。 此字段为常数。 (继承自 WaitHandle) |
属性
Handle |
已过时。
获取或设置本机操作系统句柄。 (继承自 WaitHandle) |
SafeWaitHandle |
获取或设置本机操作系统句柄。 (继承自 WaitHandle) |
方法
Close() |
释放由当前 WaitHandle 占用的所有资源。 (继承自 WaitHandle) |
CreateObjRef(Type) |
创建一个对象,该对象包含生成用于与远程对象进行通信的代理所需的全部相关信息。 (继承自 MarshalByRefObject) |
Dispose() |
释放 WaitHandle 类的当前实例所使用的所有资源。 (继承自 WaitHandle) |
Dispose(Boolean) |
当在派生类中重写时,释放 WaitHandle 使用的非托管资源,并且可选择释放托管资源。 (继承自 WaitHandle) |
Equals(Object) |
确定指定对象是否等于当前对象。 (继承自 Object) |
GetHashCode() |
作为默认哈希函数。 (继承自 Object) |
GetLifetimeService() |
已过时。
检索控制此实例的生存期策略的当前生存期服务对象。 (继承自 MarshalByRefObject) |
GetType() |
获取当前实例的 Type。 (继承自 Object) |
InitializeLifetimeService() |
已过时。
获取生存期服务对象来控制此实例的生存期策略。 (继承自 MarshalByRefObject) |
MemberwiseClone() |
创建当前 Object 的浅表副本。 (继承自 Object) |
MemberwiseClone(Boolean) |
创建当前 MarshalByRefObject 对象的浅表副本。 (继承自 MarshalByRefObject) |
OpenExisting(String) |
打开指定名称为同步事件(如果已经存在)。 |
Reset() |
将事件状态设置为非终止状态,导致线程阻止。 |
Set() |
将事件状态设置为终止状态,允许一个或多个等待线程继续。 |
ToString() |
返回表示当前对象的字符串。 (继承自 Object) |
TryOpenExisting(String, EventWaitHandle) |
打开指定的命名同步事件(如果已经存在),返回指示操作是否成功的值。 |
WaitOne() |
阻止当前线程,直到当前 WaitHandle 收到信号。 (继承自 WaitHandle) |
WaitOne(Int32) |
阻止当前线程,直到当前 WaitHandle 收到信号,同时使用 32 位带符号整数指定时间间隔(以毫秒为单位)。 (继承自 WaitHandle) |
WaitOne(Int32, Boolean) |
阻止当前线程,直到当前的 WaitHandle 收到信号为止,同时使用 32 位带符号整数指定时间间隔,并指定是否在等待之前退出同步域。 (继承自 WaitHandle) |
WaitOne(TimeSpan) |
阻止当前线程,直到当前实例收到信号,同时使用 TimeSpan 指定时间间隔。 (继承自 WaitHandle) |
WaitOne(TimeSpan, Boolean) |
阻止当前线程,直到当前实例收到信号为止,同时使用 TimeSpan 指定时间间隔,并指定是否在等待之前退出同步域。 (继承自 WaitHandle) |
显式接口实现
IDisposable.Dispose() |
此 API 支持产品基础结构,不能在代码中直接使用。 释放由 WaitHandle 使用的所有资源。 (继承自 WaitHandle) |
扩展方法
GetAccessControl(EventWaitHandle) |
返回指定的 |
SetAccessControl(EventWaitHandle, EventWaitHandleSecurity) |
设置指定事件等待句柄的安全描述符。 |
GetSafeWaitHandle(WaitHandle) |
获取本机操作系统等待句柄的安全句柄。 |
SetSafeWaitHandle(WaitHandle, SafeWaitHandle) |
设置本机操作系统等待句柄的安全句柄。 |
适用于
产品 | 版本 |
---|---|
.NET | 5.0, 6.0 RC 1 |
.NET Core | 1.0, 1.1, 2.0, 2.1, 2.2, 3.0, 3.1 |
.NET Framework | 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8 |
.NET Standard | 1.0, 1.1, 1.2, 1.3, 1.4, 1.6, 2.0, 2.1 |
UWP | 10.0 |
Xamarin.Android | 7.1 |
Xamarin.iOS | 10.8 |
Xamarin.Mac | 3.0 |
线程安全性
此类型是线程安全的。