EventWaitHandle 类

定义

表示线程同步事件。

public ref class EventWaitHandle : System::Threading::WaitHandle
public class EventWaitHandle : System.Threading.WaitHandle
[System.Runtime.InteropServices.ComVisible(true)]
public class EventWaitHandle : System.Threading.WaitHandle
type EventWaitHandle = class
    inherit WaitHandle
[<System.Runtime.InteropServices.ComVisible(true)>]
type EventWaitHandle = class
    inherit WaitHandle
Public Class EventWaitHandle
Inherits WaitHandle
继承
EventWaitHandle
继承
派生
属性

示例

下面的代码示例使用 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();
    }
}
Imports System.Threading

Public Class Example

    ' The EventWaitHandle used to demonstrate the difference
    ' between AutoReset and ManualReset synchronization events.
    '
    Private Shared ewh As EventWaitHandle

    ' 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 Shared threadCount As Long = 0

    ' An AutoReset event that allows the main thread to block
    ' until an exiting thread has decremented the count.
    '
    Private Shared clearCount As New EventWaitHandle(False, _
        EventResetMode.AutoReset)

    <MTAThread> _
    Public Shared Sub 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 i As Integer = 0 To 4
            Dim t As New Thread(AddressOf ThreadProc)
            t.Start(i)
        Next 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(threadCount) < 5
            Thread.Sleep(500)
        End While

        ' Release one thread each time the user presses ENTER,
        ' until all threads have been released.
        '
        While Interlocked.Read(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)
        End While
        Console.WriteLine()

        ' Create a ManualReset EventWaitHandle.
        '
        ewh = New EventWaitHandle(False, EventResetMode.ManualReset)

        ' Create and start five more numbered threads.
        '
        For i As Integer = 0 To 4
            Dim t As New Thread(AddressOf ThreadProc)
            t.Start(i)
        Next i

        ' Wait until all the threads have started and blocked.
        '
        While Interlocked.Read(threadCount) < 5
            Thread.Sleep(500)
        End While

        ' 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()
        
    End Sub

    Public Shared Sub ThreadProc(ByVal data As Object)
        Dim index As Integer = CInt(data)

        Console.WriteLine("Thread {0} blocks.", data)
        ' Increment the count of blocked threads.
        Interlocked.Increment(threadCount)

        ' Wait on the EventWaitHandle.
        ewh.WaitOne()

        Console.WriteLine("Thread {0} exits.", data)
        ' Decrement the count of blocked threads.
        Interlocked.Decrement(threadCount)

        ' After signaling ewh, the main thread blocks on
        ' clearCount until the signaled thread has 
        ' decremented the count. Signal it now.
        '
        clearCount.Set()
    End Sub
End Class

注解

EventWaitHandle 允许线程通过信号相互通信。 通常,在取消阻止的线程调用EventWaitHandle该方法之前,一个或多个线程会阻塞Set,释放一个或多个阻塞的线程。 线程可以通过调用 EventWaitHandlestatic Visual Basic) Shared 方法来发出WaitHandle.SignalAndWait,然后阻止线程。

Note

EventWaitHandle 类提供对命名系统同步事件的访问权限。

已发出信号的行为 EventWaitHandle 取决于其重置模式。 EventWaitHandle释放单个等待线程后,使用EventResetMode.AutoReset标志创建的创建会在发出信号后自动重置。 在 EventWaitHandle 方法获得调用前,一直向使用 EventResetMode.ManualReset 标志创建的 Reset 发出信号。

自动重置事件提供对资源的独占访问权限。 如果向自动重置事件发出信号时没有线程正在等待,此信号会一直发出到有线程尝试在等待句柄上等待。 该事件释放线程并立即重置,阻止后续线程。

手动重置事件类似于门。 如果未发出事件信号,等待事件的线程将阻止。 发出事件信号后,将释放所有等待线程,并且该事件将保持信号(即,在调用其 Reset 方法之前不会阻止后续等待)。 如果一个线程必须完成活动,然后才能继续其他线程,则手动重置事件非常有用。

EventWaitHandle 对象可与 staticShared 方法 Visual Basic中的 WaitHandle.WaitAllWaitHandle.WaitAny) 一起使用。

有关详细信息,请参阅同步基元概述文章的 Thread 交互或信号部分。

注意

默认情况下,命名事件不限于创建它的用户。 其他用户可能能够打开和使用该事件,包括通过设置或重置事件来干扰事件。 若要限制对特定用户的访问,可以使用构造函数重载或在 EventWaitHandleAcl 创建命名事件时传入 EventWaitHandleSecurity 。 避免在可能具有不受信任的用户运行代码的系统上使用命名事件,而不受访问限制。

构造函数

名称 说明
EventWaitHandle(Boolean, EventResetMode, String, Boolean, EventWaitHandleSecurity)

初始化类的新实例 EventWaitHandle ,指定是否最初发出等待句柄的信号(如果由于此调用而创建),无论是自动重置还是手动重置系统同步事件的名称、调用后其值的布尔变量指示是否已创建命名系统事件,以及在创建命名事件时应用于命名事件的访问控制安全性。

EventWaitHandle(Boolean, EventResetMode, String, Boolean)

初始化类的新实例 EventWaitHandle ,指定是否最初发出等待句柄的信号(如果由于此调用而创建),无论是自动重置还是手动重置系统同步事件的名称,以及调用后其值的布尔变量指示是否创建了命名系统事件。

EventWaitHandle(Boolean, EventResetMode, String, NamedWaitHandleOptions, Boolean)

初始化类的新实例 EventWaitHandle ,指定在调用后创建等待句柄时是否最初发出信号,无论是自动重置还是手动重置系统同步事件、设置用户范围和会话范围访问的选项,以及调用后的值是否指示已命名系统事件是否已创建布尔变量。

EventWaitHandle(Boolean, EventResetMode, String, NamedWaitHandleOptions)

初始化类的新实例 EventWaitHandle ,指定是否最初发出等待句柄的信号(如果由于此调用而创建),无论是自动重置还是手动重置、系统同步事件的名称,以及设置用户范围和会话范围访问权限的选项。

EventWaitHandle(Boolean, EventResetMode, String)

初始化类的新实例 EventWaitHandle ,指定是否最初发出等待句柄的信号(如果由于此调用而创建),无论是自动重置还是手动重置,以及系统同步事件的名称。

EventWaitHandle(Boolean, EventResetMode)

初始化类的新实例 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)
GetAccessControl()

获取一个 EventWaitHandleSecurity 对象,该对象表示由当前 EventWaitHandle 对象表示的命名系统事件的访问控制安全性。

GetHashCode()

用作默认哈希函数。

(继承自 Object)
GetLifetimeService()
已过时.

检索控制此实例的生存期策略的当前生存期服务对象。

(继承自 MarshalByRefObject)
GetType()

获取当前实例的 Type

(继承自 Object)
InitializeLifetimeService()
已过时.

获取生存期服务对象来控制此实例的生存期策略。

(继承自 MarshalByRefObject)
MemberwiseClone()

创建当前 Object的浅表副本。

(继承自 Object)
MemberwiseClone(Boolean)

创建当前 MarshalByRefObject 对象的浅表副本。

(继承自 MarshalByRefObject)
OpenExisting(String, EventWaitHandleRights)

使用所需的安全访问打开指定的命名同步事件(如果已存在)。

OpenExisting(String, NamedWaitHandleOptions)

打开指定的命名同步事件(如果已存在)。 如果选项仅设置为当前用户,则为调用用户验证对象的访问控制。

OpenExisting(String)

打开指定的命名同步事件(如果已存在)。

Reset()

将事件的状态设置为非对齐状态,导致线程被阻止。

Set()

将事件的状态设置为信号,允许一个或多个等待线程继续。

SetAccessControl(EventWaitHandleSecurity)

设置命名系统事件的访问控制安全性。

ToString()

返回一个表示当前对象的字符串。

(继承自 Object)
TryOpenExisting(String, EventWaitHandle)

打开指定的命名同步事件(如果已存在),并返回一个值,该值指示操作是否成功。

TryOpenExisting(String, EventWaitHandleRights, EventWaitHandle)

使用所需的安全访问打开指定的命名同步事件(如果已存在),并返回一个值,该值指示操作是否成功。

TryOpenExisting(String, NamedWaitHandleOptions, EventWaitHandle)

打开指定的命名同步事件(如果已存在),并返回一个值,该值指示操作是否成功。 如果选项仅设置为当前用户,则为调用用户验证对象的访问控制。

WaitOne()

阻止当前线程,直到当前 WaitHandle 接收信号。

(继承自 WaitHandle)
WaitOne(Int32, Boolean)

阻止当前线程,直到当前 WaitHandle 接收信号,使用 32 位有符号整数指定时间间隔,并指定是否在等待之前退出同步域。

(继承自 WaitHandle)
WaitOne(Int32)

阻止当前线程,直到当前 WaitHandle 接收信号,使用 32 位有符号整数指定时间间隔(以毫秒为单位)。

(继承自 WaitHandle)
WaitOne(TimeSpan, Boolean)

阻止当前线程,直到当前实例收到信号,使用指定 TimeSpan 时间间隔并指定是否在等待之前退出同步域。

(继承自 WaitHandle)
WaitOne(TimeSpan)

阻止当前线程,直到当前实例收到信号,并使用 TimeSpan 指定时间间隔。

(继承自 WaitHandle)

显式接口实现

名称 说明
IDisposable.Dispose()

此 API 支持产品基础结构,不能在代码中直接使用。

释放该 WaitHandle命令使用的所有资源。

(继承自 WaitHandle)

扩展方法

名称 说明
GetAccessControl(EventWaitHandle)

返回指定 handle的安全描述符。

GetSafeWaitHandle(WaitHandle)

获取本机操作系统等待句柄的安全句柄。

SetAccessControl(EventWaitHandle, EventWaitHandleSecurity)

设置指定事件等待句柄的安全描述符。

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

设置本机操作系统等待句柄的安全句柄。

适用于

线程安全性

此类型是线程安全的。

另请参阅