EventWaitHandle 构造函数

定义

初始化 EventWaitHandle 类的新实例。

重载

EventWaitHandle(Boolean, EventResetMode)

初始化 EventWaitHandle 类的新实例,并指定等待句柄最初是否处于终止状态,以及它是自动重置还是手动重置。

EventWaitHandle(Boolean, EventResetMode, String)

初始化 EventWaitHandle 类的新实例,并指定在此调用后创建的等待句柄最初是否处于终止状态,它是自动重置还是手动重置,以及系统同步事件的名称。

EventWaitHandle(Boolean, EventResetMode, String, Boolean)

初始化 EventWaitHandle 类的新实例,指定如果将等待句柄作为此调用的结果而创建,最初是否通过信号通知此句柄;指定是否自动或手动重置系统同步事件的名称,以及一个布尔变量,在调用后其值指示是否创建了命名的系统事件。

EventWaitHandle(Boolean, EventResetMode, String, Boolean, EventWaitHandleSecurity)

初始化 EventWaitHandle 类的新实例,指定如果等待句柄作为此调用的结果而创建,最初是否通过信号通知此句柄;指定是否自动或手动重置系统同步事件的名称和布尔变量,其值在该调用后将指示是否创建了已命名系统事件,以及是否将访问控制安全性应用到命名事件(如果已创建该事件)。

EventWaitHandle(Boolean, EventResetMode)

初始化 EventWaitHandle 类的新实例,并指定等待句柄最初是否处于终止状态,以及它是自动重置还是手动重置。

public:
 EventWaitHandle(bool initialState, System::Threading::EventResetMode mode);
public EventWaitHandle (bool initialState, System.Threading.EventResetMode mode);
new System.Threading.EventWaitHandle : bool * System.Threading.EventResetMode -> System.Threading.EventWaitHandle
Public Sub New (initialState As Boolean, mode As EventResetMode)

参数

initialState
Boolean

如果为 true,则将初始状态设置为终止;如果为 false,则将初始状态设置为非终止。

mode
EventResetMode

其中一个 EventResetMode 值,它确定是自动还是手动重置事件。

例外

mode 枚举值超出了合法范围。

示例

下面的代码示例使用 SignalAndWait(WaitHandle, WaitHandle) 方法重载允许main线程向阻塞的线程发出信号,然后等待线程完成任务。

该示例启动五个 EventWaitHandle 线程,并允许它们阻止使用 EventResetMode.AutoReset 标志创建的 ,然后在用户每次按 Enter 键时释放一个线程。 然后,该示例将另外五个 EventWaitHandle 线程排队,并使用使用 EventResetMode.ManualReset 标志创建的 释放它们。

using namespace System;
using namespace System::Threading;

public ref class Example
{
private:
   // The EventWaitHandle used to demonstrate the difference
   // between AutoReset and ManualReset synchronization events.
   //
   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.
   //
   static __int64 threadCount = 0;

   // An AutoReset event that allows the main thread to block
   // until an exiting thread has decremented the count.
   //
   static EventWaitHandle^ clearCount =
      gcnew EventWaitHandle( false,EventResetMode::AutoReset );

public:
   [MTAThread]
   static void main()
   {
      // Create an AutoReset EventWaitHandle.
      //
      ewh = gcnew 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 = gcnew Thread(
            gcnew 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( threadCount ) < 5 )
      {
         Thread::Sleep( 500 );
      }

      // Release one thread each time the user presses ENTER,
      // until all threads have been released.
      //
      while ( Interlocked::Read( threadCount ) > 0 )
      {
         Console::WriteLine( L"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 = gcnew EventWaitHandle( false,EventResetMode::ManualReset );
      
      // Create and start five more numbered threads.
      //
      for ( int i = 0; i <= 4; i++ )
      {
         Thread^ t = gcnew Thread(
            gcnew ParameterizedThreadStart( ThreadProc ) );
         t->Start( i );
      }
      
      // Wait until all the threads have started and blocked.
      //
      while ( Interlocked::Read( threadCount ) < 5 )
      {
         Thread::Sleep( 500 );
      }

      // Because the EventWaitHandle was created with
      // ManualReset mode, signaling it releases all the
      // waiting threads.
      //
      Console::WriteLine( L"Press ENTER to release the waiting threads." );
      Console::ReadLine();
      ewh->Set();

   }

   static void ThreadProc( Object^ data )
   {
      int index = static_cast<Int32>(data);

      Console::WriteLine( L"Thread {0} blocks.", data );
      // Increment the count of blocked threads.
      Interlocked::Increment( threadCount );
      
      // Wait on the EventWaitHandle.
      ewh->WaitOne();

      Console::WriteLine( L"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();
   }
};
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

注解

如果事件的初始状态未签名,则等待事件的线程将阻塞。 如果发出了初始状态信号,并且 ManualResetmode指定了 标志,则等待事件的线程不会阻塞。 如果初始状态已发出信号,并且 modeAutoReset,则等待事件的第一个线程将立即释放,之后事件将重置,后续线程将阻塞。

另请参阅

适用于

EventWaitHandle(Boolean, EventResetMode, String)

初始化 EventWaitHandle 类的新实例,并指定在此调用后创建的等待句柄最初是否处于终止状态,它是自动重置还是手动重置,以及系统同步事件的名称。

public:
 EventWaitHandle(bool initialState, System::Threading::EventResetMode mode, System::String ^ name);
[System.Security.SecurityCritical]
public EventWaitHandle (bool initialState, System.Threading.EventResetMode mode, string name);
public EventWaitHandle (bool initialState, System.Threading.EventResetMode mode, string? name);
public EventWaitHandle (bool initialState, System.Threading.EventResetMode mode, string name);
[<System.Security.SecurityCritical>]
new System.Threading.EventWaitHandle : bool * System.Threading.EventResetMode * string -> System.Threading.EventWaitHandle
new System.Threading.EventWaitHandle : bool * System.Threading.EventResetMode * string -> System.Threading.EventWaitHandle
Public Sub New (initialState As Boolean, mode As EventResetMode, name As String)

参数

initialState
Boolean

如果将命名事件作为此调用的结果创建时将初始状态设置为通过信号通知,则为 true;如果将其设置为不通过信号通知,则为 false

mode
EventResetMode

其中一个 EventResetMode 值,它确定是自动还是手动重置事件。

name
String

如果要与其他进程共享同步对象,则为名称;否则为 null 或空字符串。 该名称区分大小写。 反斜杠字符 (\) 是保留的,只能用于指定命名空间。 有关命名空间的详细信息,请参阅备注部分。 根据操作系统,名称可能会有进一步的限制。 例如,在基于 Unix 的操作系统上,排除命名空间后的名称必须是有效的文件名。

属性

例外

name 无效。 导致这种情况的原因有很多,包括操作系统可能会施加的一些限制,例如未知前缀或无效字符。 请注意,名称和常见前缀“Global\”和“Local\”区分大小写。

还有其他一些错误。 HResult 属性可能提供更多信息。

仅限 Windows:name 指定了未知命名空间。 有关详细信息,请参阅对象名称

name 太长。 长度限制可能取决于操作系统或配置。

命名事件存在且具有访问控制安全性,但用户不具有 FullControl

无法创建具有提供的 name 的同步对象。 不同类型的同步对象可能具有相同的名称。

mode 枚举值超出了合法范围。

仅限 .NET Framework:name 的长度超过 MAX_PATH(260 个字符)。

注解

name可以使用 或 Local\ 作为前缀Global\来指定命名空间。 Global指定命名空间后,可以与系统上的任何进程共享同步对象。 如果指定了 Local 命名空间(如果未指定命名空间,这也是默认命名空间),则同步对象可以与同一会话中的进程共享。 在 Windows 上,会话是登录会话,服务通常在不同的非交互式会话中运行。 在类似 Unix 的操作系统上,每个 shell 都有自己的会话。 会话本地同步对象可能适合在具有父/子关系的进程之间进行同步,这些进程都在同一会话中运行。 有关 Windows 上的同步对象名称的详细信息,请参阅 对象名称

如果提供了 , name 并且命名空间中已存在请求类型的同步对象,则会打开现有的同步对象。 如果命名空间中已存在不同类型的同步对象, WaitHandleCannotBeOpenedException 则会引发 。 否则,将创建新的同步对象。

如果已存在具有为 name 参数指定名称的系统事件,则忽略该 initialState 参数。

注意

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

重要

将此构造函数用于命名系统事件时,请为 initialState指定 false 。 此构造函数无法确定是否已创建命名系统事件,因此无法对命名事件的状态做出任何假设。 若要确定是否创建了命名事件,请使用 EventWaitHandle(Boolean, EventResetMode, String, Boolean) 构造函数或 EventWaitHandle(Boolean, EventResetMode, String, Boolean, EventWaitHandleSecurity) 构造函数。

如果事件的初始状态未签名,则等待事件的线程将阻塞。 如果发出了初始状态信号,并且 ManualResetmode指定了 标志,则等待事件的线程不会阻塞。 如果初始状态已发出信号,并且 modeAutoReset,则等待事件的第一个线程将立即释放,之后事件将重置,后续线程将阻塞。

另请参阅

适用于

EventWaitHandle(Boolean, EventResetMode, String, Boolean)

初始化 EventWaitHandle 类的新实例,指定如果将等待句柄作为此调用的结果而创建,最初是否通过信号通知此句柄;指定是否自动或手动重置系统同步事件的名称,以及一个布尔变量,在调用后其值指示是否创建了命名的系统事件。

public:
 EventWaitHandle(bool initialState, System::Threading::EventResetMode mode, System::String ^ name, [Runtime::InteropServices::Out] bool % createdNew);
[System.Security.SecurityCritical]
public EventWaitHandle (bool initialState, System.Threading.EventResetMode mode, string name, out bool createdNew);
public EventWaitHandle (bool initialState, System.Threading.EventResetMode mode, string? name, out bool createdNew);
public EventWaitHandle (bool initialState, System.Threading.EventResetMode mode, string name, out bool createdNew);
[<System.Security.SecurityCritical>]
new System.Threading.EventWaitHandle : bool * System.Threading.EventResetMode * string * bool -> System.Threading.EventWaitHandle
new System.Threading.EventWaitHandle : bool * System.Threading.EventResetMode * string * bool -> System.Threading.EventWaitHandle
Public Sub New (initialState As Boolean, mode As EventResetMode, name As String, ByRef createdNew As Boolean)

参数

initialState
Boolean

如果将命名事件作为此调用的结果创建时将初始状态设置为通过信号通知,则为 true;如果将其设置为不通过信号通知,则为 false

mode
EventResetMode

其中一个 EventResetMode 值,它确定是自动还是手动重置事件。

name
String

如果要与其他进程共享同步对象,则为名称;否则为 null 或空字符串。 该名称区分大小写。 反斜杠字符 (\) 是保留的,只能用于指定命名空间。 有关命名空间的详细信息,请参阅备注部分。 根据操作系统,名称可能会有进一步的限制。 例如,在基于 Unix 的操作系统上,排除命名空间后的名称必须是有效的文件名。

createdNew
Boolean

在此方法返回时,如果创建了本地事件(即,如果 nametrue 或空字符串)或指定的命名系统事件,则包含 null;如果指定的命名系统事件已存在,则为 false。 此参数未经初始化即被传递。

属性

例外

name 无效。 导致这种情况的原因有很多,包括操作系统可能会施加的一些限制,例如未知前缀或无效字符。 请注意,名称和常见前缀“Global\”和“Local\”区分大小写。

还有其他一些错误。 HResult 属性可能提供更多信息。

仅限 Windows:name 指定了未知命名空间。 有关详细信息,请参阅对象名称

name 太长。 长度限制可能取决于操作系统或配置。

命名事件存在且具有访问控制安全性,但用户不具有 FullControl

无法创建具有提供的 name 的同步对象。 不同类型的同步对象可能具有相同的名称。

mode 枚举值超出了合法范围。

仅限 .NET Framework:name 的长度超过 MAX_PATH(260 个字符)。

注解

name可以使用 或 Local\ 作为前缀Global\来指定命名空间。 Global指定命名空间后,可以与系统上的任何进程共享同步对象。 Local指定命名空间时(未指定命名空间时也是默认值),可以与同一会话中的进程共享同步对象。 在 Windows 上,会话是登录会话,服务通常在不同的非交互式会话中运行。 在类似于 Unix 的操作系统上,每个 shell 都有其自己的会话。 会话本地同步对象可能适合用于使用父/子关系(在这些进程都在同一会话中运行)之间进行同步。 有关 Windows 上的同步对象名称的详细信息,请参阅 对象名称

如果提供了 , name 并且命名空间中已存在请求类型的同步对象,则会打开现有的同步对象。 如果命名空间中已存在不同类型的同步对象, WaitHandleCannotBeOpenedException 则会引发 。 否则,将创建新的同步对象。

如果已存在具有为 name 参数指定名称的系统事件,则会忽略该 initialState 参数。 调用此构造函数后,使用为 ref Visual Basic createdNew) 中的参数 (ByRef 参数指定的变量中的值来确定命名系统事件是否已存在或已创建。

如果事件的初始状态未对齐,则等待事件的线程将阻塞。 如果发出初始状态信号,并且 ManualResetmode指定标志,则等待事件的线程不会阻止。 如果初始状态已发出信号,并且 modeAutoReset,则立即释放等待事件的第一个线程,然后事件将重置,后续线程将阻止。

注意

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

另请参阅

适用于

EventWaitHandle(Boolean, EventResetMode, String, Boolean, EventWaitHandleSecurity)

初始化 EventWaitHandle 类的新实例,指定如果等待句柄作为此调用的结果而创建,最初是否通过信号通知此句柄;指定是否自动或手动重置系统同步事件的名称和布尔变量,其值在该调用后将指示是否创建了已命名系统事件,以及是否将访问控制安全性应用到命名事件(如果已创建该事件)。

public:
 EventWaitHandle(bool initialState, System::Threading::EventResetMode mode, System::String ^ name, [Runtime::InteropServices::Out] bool % createdNew, System::Security::AccessControl::EventWaitHandleSecurity ^ eventSecurity);
public EventWaitHandle (bool initialState, System.Threading.EventResetMode mode, string name, out bool createdNew, System.Security.AccessControl.EventWaitHandleSecurity eventSecurity);
[System.Security.SecurityCritical]
public EventWaitHandle (bool initialState, System.Threading.EventResetMode mode, string name, out bool createdNew, System.Security.AccessControl.EventWaitHandleSecurity eventSecurity);
new System.Threading.EventWaitHandle : bool * System.Threading.EventResetMode * string * bool * System.Security.AccessControl.EventWaitHandleSecurity -> System.Threading.EventWaitHandle
[<System.Security.SecurityCritical>]
new System.Threading.EventWaitHandle : bool * System.Threading.EventResetMode * string * bool * System.Security.AccessControl.EventWaitHandleSecurity -> System.Threading.EventWaitHandle
Public Sub New (initialState As Boolean, mode As EventResetMode, name As String, ByRef createdNew As Boolean, eventSecurity As EventWaitHandleSecurity)

参数

initialState
Boolean

如果将命名事件作为此调用的结果创建时将初始状态设置为通过信号通知,则为 true;如果将其设置为不通过信号通知,则为 false

mode
EventResetMode

其中一个 EventResetMode 值,它确定是自动还是手动重置事件。

name
String

如果要与其他进程共享同步对象,则为名称;否则为 null 或空字符串。 该名称区分大小写。 反斜杠字符 (\) 是保留的,只能用于指定命名空间。 有关命名空间的详细信息,请参阅备注部分。 根据操作系统,名称可能会有进一步的限制。 例如,在基于 Unix 的操作系统上,排除命名空间后的名称必须是有效的文件名。

createdNew
Boolean

在此方法返回时,如果创建了本地事件(即,如果 nametrue 或空字符串)或指定的命名系统事件,则包含 null;如果指定的命名系统事件已存在,则为 false。 此参数未经初始化即被传递。

eventSecurity
EventWaitHandleSecurity

一个 EventWaitHandleSecurity 对象,该对象表示应用到命名系统事件的访问控制安全性。

属性

例外

name 无效。 导致这种情况的原因有很多,包括操作系统可能会施加的一些限制,例如未知前缀或无效字符。 请注意,名称和通用前缀“Global\”和“Local\”区分大小写。

还有一些其他错误。 HResult 属性可能提供更多信息。

仅限 Windows:name 指定了未知命名空间。 有关详细信息,请参阅对象名称

name 太长。 长度限制可能取决于操作系统或配置。

命名事件存在且具有访问控制安全性,但用户不具有 FullControl

无法创建具有提供的 name 的同步对象。 不同类型的同步对象可能具有相同的名称。

mode 枚举值超出了合法范围。

仅限 .NET Framework:name 的长度超过 MAX_PATH(260 个字符)。

示例

以下代码示例演示具有访问控制安全性的命名系统事件的跨进程行为。 该示例使用 OpenExisting(String) 方法重载来测试命名事件是否存在。

如果该事件不存在,则会使用初始所有权和访问控制安全性创建该事件,该安全性将拒绝当前用户使用该事件的权利,但授予对事件进行读取和更改权限的权限。

如果从两个命令窗口运行编译的示例,则第二个副本将在调用 OpenExisting(String)时引发访问冲突异常。 捕获异常,该示例使用 OpenExisting(String, EventWaitHandleRights) 方法重载等待具有读取和更改权限所需的权限的事件。

更改权限后,事件将打开,其中包含等待它并发出信号所需的权限。 如果从第三个命令窗口运行已编译的示例,则使用新权限运行该示例。

using namespace System;
using namespace System::Threading;
using namespace System::Security::AccessControl;
using namespace System::Security::Permissions;

public ref class Example
{
public:
   [SecurityPermissionAttribute(SecurityAction::Demand,Flags=SecurityPermissionFlag::UnmanagedCode)]
   static void Main()
   {
      String^ ewhName = L"EventWaitHandleExample5";

      EventWaitHandle^ ewh = nullptr;
      bool doesNotExist = false;
      bool unauthorized = false;
      
      // The value of this variable is set by the event
      // constructor. It is true if the named system event was
      // created, and false if the named event already existed.
      //
      bool wasCreated;
      
      // Attempt to open the named event.
      try
      {
         // Open the event with (EventWaitHandleRights.Synchronize
         // | EventWaitHandleRights.Modify), to wait on and
         // signal the named event.
         //
         ewh = EventWaitHandle::OpenExisting( ewhName );
      }
      catch ( WaitHandleCannotBeOpenedException^ ) 
      {
         Console::WriteLine( L"Named event does not exist." );
         doesNotExist = true;
      }
      catch ( UnauthorizedAccessException^ ex ) 
      {
         Console::WriteLine( L"Unauthorized access: {0}", ex->Message );
         unauthorized = true;
      }

      // There are three cases: (1) The event does not exist.
      // (2) The event exists, but the current user doesn't
      // have access. (3) The event exists and the user has
      // access.
      //
      if ( doesNotExist )
      {
         // The event does not exist, so create it.

         // Create an access control list (ACL) that denies the
         // current user the right to wait on or signal the
         // event, but allows the right to read and change
         // security information for the event.
         //
         String^ user = String::Concat( Environment::UserDomainName, L"\\",
            Environment::UserName );
         EventWaitHandleSecurity^ ewhSec = gcnew EventWaitHandleSecurity;
         //following constructor fails
         EventWaitHandleAccessRule^ rule = gcnew EventWaitHandleAccessRule(
            user,
            static_cast<EventWaitHandleRights>(
               EventWaitHandleRights::Synchronize | 
               EventWaitHandleRights::Modify),
            AccessControlType::Deny );
         ewhSec->AddAccessRule( rule );

         rule = gcnew EventWaitHandleAccessRule( user,
            static_cast<EventWaitHandleRights>(
               EventWaitHandleRights::ReadPermissions | 
               EventWaitHandleRights::ChangePermissions),
            AccessControlType::Allow );
         ewhSec->AddAccessRule( rule );
         
         // Create an EventWaitHandle object that represents
         // the system event named by the constant 'ewhName',
         // initially signaled, with automatic reset, and with
         // the specified security access. The Boolean value that
         // indicates creation of the underlying system object
         // is placed in wasCreated.
         //
         ewh = gcnew EventWaitHandle( true,
            EventResetMode::AutoReset,
            ewhName,
            wasCreated,
            ewhSec );
         
         // If the named system event was created, it can be
         // used by the current instance of this program, even
         // though the current user is denied access. The current
         // program owns the event. Otherwise, exit the program.
         //
         if ( wasCreated )
         {
            Console::WriteLine( L"Created the named event." );
         }
         else
         {
            Console::WriteLine( L"Unable to create the event." );
            return;
         }
      }
      else if ( unauthorized )
      {
         // Open the event to read and change the access control
         // security. The access control security defined above
         // allows the current user to do this.
         //
         try
         {
            ewh = EventWaitHandle::OpenExisting( ewhName, 
               static_cast<EventWaitHandleRights>(
                  EventWaitHandleRights::ReadPermissions |
                  EventWaitHandleRights::ChangePermissions) );
            
            // Get the current ACL. This requires
            // EventWaitHandleRights.ReadPermissions.
            EventWaitHandleSecurity^ ewhSec = ewh->GetAccessControl();
            String^ user = String::Concat( Environment::UserDomainName, L"\\",
               Environment::UserName );
            
            // First, the rule that denied the current user
            // the right to enter and release the event must
            // be removed.
            EventWaitHandleAccessRule^ rule = gcnew EventWaitHandleAccessRule(
               user,
               static_cast<EventWaitHandleRights>(
                  EventWaitHandleRights::Synchronize |
                  EventWaitHandleRights::Modify),
               AccessControlType::Deny );
            ewhSec->RemoveAccessRule( rule );
            
            // Now grant the user the correct rights.
            //
            rule = gcnew EventWaitHandleAccessRule( user,
               static_cast<EventWaitHandleRights>(
                  EventWaitHandleRights::Synchronize |
                  EventWaitHandleRights::Modify),
               AccessControlType::Allow );
            ewhSec->AddAccessRule( rule );
            
            // Update the ACL. This requires
            // EventWaitHandleRights.ChangePermissions.
            ewh->SetAccessControl( ewhSec );
            Console::WriteLine( L"Updated event security." );
            
            // Open the event with (EventWaitHandleRights.Synchronize
            // | EventWaitHandleRights.Modify), the rights required
            // to wait on and signal the event.
            //
            ewh = EventWaitHandle::OpenExisting( ewhName );
         }
         catch ( UnauthorizedAccessException^ ex ) 
         {
            Console::WriteLine( L"Unable to change permissions: {0}",
               ex->Message );
            return;
         }

      }
      
      // Wait on the event, and hold it until the program
      // exits.
      //
      try
      {
         Console::WriteLine( L"Wait on the event." );
         ewh->WaitOne();
         Console::WriteLine( L"Event was signaled." );
         Console::WriteLine( L"Press the Enter key to signal the event and exit." );
         Console::ReadLine();
      }
      catch ( UnauthorizedAccessException^ ex ) 
      {
         Console::WriteLine( L"Unauthorized access: {0}", ex->Message );
      }
      finally
      {
         ewh->Set();
      }
   }
};

int main()
{
   Example::Main();
}
using System;
using System.Threading;
using System.Security.AccessControl;

internal class Example
{
    internal static void Main()
    {
        const string ewhName = "EventWaitHandleExample5";

        EventWaitHandle ewh = null;
        bool doesNotExist = false;
        bool unauthorized = false;

        // The value of this variable is set by the event
        // constructor. It is true if the named system event was
        // created, and false if the named event already existed.
        //
        bool wasCreated;

        // Attempt to open the named event.
        try
        {
            // Open the event with (EventWaitHandleRights.Synchronize
            // | EventWaitHandleRights.Modify), to wait on and 
            // signal the named event.
            //
            ewh = EventWaitHandle.OpenExisting(ewhName);
        }
        catch (WaitHandleCannotBeOpenedException)
        {
            Console.WriteLine("Named event does not exist.");
            doesNotExist = true;
        }
        catch (UnauthorizedAccessException ex)
        {
            Console.WriteLine("Unauthorized access: {0}", ex.Message);
            unauthorized = true;
        }

        // There are three cases: (1) The event does not exist.
        // (2) The event exists, but the current user doesn't 
        // have access. (3) The event exists and the user has
        // access.
        //
        if (doesNotExist)
        {
            // The event does not exist, so create it.

            // Create an access control list (ACL) that denies the
            // current user the right to wait on or signal the 
            // event, but allows the right to read and change
            // security information for the event.
            //
            string user = Environment.UserDomainName + "\\"
                + Environment.UserName;
            EventWaitHandleSecurity ewhSec = 
                new EventWaitHandleSecurity();

            EventWaitHandleAccessRule rule = 
                new EventWaitHandleAccessRule(user, 
                    EventWaitHandleRights.Synchronize | 
                    EventWaitHandleRights.Modify, 
                    AccessControlType.Deny);
            ewhSec.AddAccessRule(rule);

            rule = new EventWaitHandleAccessRule(user, 
                EventWaitHandleRights.ReadPermissions | 
                EventWaitHandleRights.ChangePermissions, 
                AccessControlType.Allow);
            ewhSec.AddAccessRule(rule);

            // Create an EventWaitHandle object that represents
            // the system event named by the constant 'ewhName', 
            // initially signaled, with automatic reset, and with
            // the specified security access. The Boolean value that 
            // indicates creation of the underlying system object
            // is placed in wasCreated.
            //
            ewh = new EventWaitHandle(true, 
                EventResetMode.AutoReset, 
                ewhName, 
                out wasCreated, 
                ewhSec);

            // If the named system event was created, it can be
            // used by the current instance of this program, even 
            // though the current user is denied access. The current
            // program owns the event. Otherwise, exit the program.
            // 
            if (wasCreated)
            {
                Console.WriteLine("Created the named event.");
            }
            else
            {
                Console.WriteLine("Unable to create the event.");
                return;
            }
        }
        else if (unauthorized)
        {
            // Open the event to read and change the access control
            // security. The access control security defined above
            // allows the current user to do this.
            //
            try
            {
                ewh = EventWaitHandle.OpenExisting(ewhName, 
                    EventWaitHandleRights.ReadPermissions | 
                    EventWaitHandleRights.ChangePermissions);

                // Get the current ACL. This requires 
                // EventWaitHandleRights.ReadPermissions.
                EventWaitHandleSecurity ewhSec = ewh.GetAccessControl();
                
                string user = Environment.UserDomainName + "\\"
                    + Environment.UserName;

                // First, the rule that denied the current user 
                // the right to enter and release the event must
                // be removed.
                EventWaitHandleAccessRule rule = 
                    new EventWaitHandleAccessRule(user, 
                        EventWaitHandleRights.Synchronize | 
                        EventWaitHandleRights.Modify, 
                        AccessControlType.Deny);
                ewhSec.RemoveAccessRule(rule);

                // Now grant the user the correct rights.
                // 
                rule = new EventWaitHandleAccessRule(user, 
                    EventWaitHandleRights.Synchronize | 
                    EventWaitHandleRights.Modify, 
                    AccessControlType.Allow);
                ewhSec.AddAccessRule(rule);

                // Update the ACL. This requires
                // EventWaitHandleRights.ChangePermissions.
                ewh.SetAccessControl(ewhSec);

                Console.WriteLine("Updated event security.");

                // Open the event with (EventWaitHandleRights.Synchronize 
                // | EventWaitHandleRights.Modify), the rights required
                // to wait on and signal the event.
                //
                ewh = EventWaitHandle.OpenExisting(ewhName);
            }
            catch (UnauthorizedAccessException ex)
            {
                Console.WriteLine("Unable to change permissions: {0}",
                    ex.Message);
                return;
            }
        }

        // Wait on the event, and hold it until the program
        // exits.
        //
        try
        {
            Console.WriteLine("Wait on the event.");
            ewh.WaitOne();
            Console.WriteLine("Event was signaled.");
            Console.WriteLine("Press the Enter key to signal the event and exit.");
            Console.ReadLine();
        }
        catch (UnauthorizedAccessException ex)
        {
            Console.WriteLine("Unauthorized access: {0}", ex.Message);
        }
        finally
        {
            ewh.Set();
        }
    }
}
Imports System.Threading
Imports System.Security.AccessControl

Friend Class Example

    <MTAThread> _
    Friend Shared Sub Main()
        Const ewhName As String = "EventWaitHandleExample5"

        Dim ewh As EventWaitHandle = Nothing
        Dim doesNotExist as Boolean = False
        Dim unauthorized As Boolean = False

        ' The value of this variable is set by the event
        ' constructor. It is True if the named system event was
        ' created, and False if the named event already existed.
        '
        Dim wasCreated As Boolean

        ' Attempt to open the named event.
        Try
            ' Open the event with (EventWaitHandleRights.Synchronize
            ' Or EventWaitHandleRights.Modify), to wait on and 
            ' signal the named event.
            '
            ewh = EventWaitHandle.OpenExisting(ewhName)
        Catch ex As WaitHandleCannotBeOpenedException
            Console.WriteLine("Named event does not exist.")
            doesNotExist = True
        Catch ex As UnauthorizedAccessException
            Console.WriteLine("Unauthorized access: {0}", ex.Message)
            unauthorized = True
        End Try

        ' There are three cases: (1) The event does not exist.
        ' (2) The event exists, but the current user doesn't 
        ' have access. (3) The event exists and the user has
        ' access.
        '
        If doesNotExist Then
            ' The event does not exist, so create it.

            ' Create an access control list (ACL) that denies the
            ' current user the right to wait on or signal the 
            ' event, but allows the right to read and change
            ' security information for the event.
            '
            Dim user As String = Environment.UserDomainName _ 
                & "\" & Environment.UserName
            Dim ewhSec As New EventWaitHandleSecurity()

            Dim rule As New EventWaitHandleAccessRule(user, _
                EventWaitHandleRights.Synchronize Or _
                EventWaitHandleRights.Modify, _
                AccessControlType.Deny)
            ewhSec.AddAccessRule(rule)

            rule = New EventWaitHandleAccessRule(user, _
                EventWaitHandleRights.ReadPermissions Or _
                EventWaitHandleRights.ChangePermissions, _
                AccessControlType.Allow)
            ewhSec.AddAccessRule(rule)

            ' Create an EventWaitHandle object that represents
            ' the system event named by the constant 'ewhName', 
            ' initially signaled, with automatic reset, and with
            ' the specified security access. The Boolean value that 
            ' indicates creation of the underlying system object
            ' is placed in wasCreated.
            '
            ewh = New EventWaitHandle(True, _
                EventResetMode.AutoReset, ewhName, _
                wasCreated, ewhSec)

            ' If the named system event was created, it can be
            ' used by the current instance of this program, even 
            ' though the current user is denied access. The current
            ' program owns the event. Otherwise, exit the program.
            ' 
            If wasCreated Then
                Console.WriteLine("Created the named event.")
            Else
                Console.WriteLine("Unable to create the event.")
                Return
            End If

        ElseIf unauthorized Then

            ' Open the event to read and change the access control
            ' security. The access control security defined above
            ' allows the current user to do this.
            '
            Try
                ewh = EventWaitHandle.OpenExisting(ewhName, _
                    EventWaitHandleRights.ReadPermissions Or _
                    EventWaitHandleRights.ChangePermissions)

                ' Get the current ACL. This requires 
                ' EventWaitHandleRights.ReadPermissions.
                Dim ewhSec As EventWaitHandleSecurity = _
                    ewh.GetAccessControl()
                
                Dim user As String = Environment.UserDomainName _ 
                    & "\" & Environment.UserName

                ' First, the rule that denied the current user 
                ' the right to enter and release the event must
                ' be removed.
                Dim rule As New EventWaitHandleAccessRule(user, _
                    EventWaitHandleRights.Synchronize Or _
                    EventWaitHandleRights.Modify, _
                    AccessControlType.Deny)
                ewhSec.RemoveAccessRule(rule)

                ' Now grant the user the correct rights.
                ' 
                rule = New EventWaitHandleAccessRule(user, _
                    EventWaitHandleRights.Synchronize Or _
                    EventWaitHandleRights.Modify, _
                    AccessControlType.Allow)
                ewhSec.AddAccessRule(rule)

                ' Update the ACL. This requires
                ' EventWaitHandleRights.ChangePermissions.
                ewh.SetAccessControl(ewhSec)

                Console.WriteLine("Updated event security.")

                ' Open the event with (EventWaitHandleRights.Synchronize 
                ' Or EventWaitHandleRights.Modify), the rights required
                ' to wait on and signal the event.
                '
                ewh = EventWaitHandle.OpenExisting(ewhName)

            Catch ex As UnauthorizedAccessException
                Console.WriteLine("Unable to change permissions: {0}", _
                    ex.Message)
                Return
            End Try

        End If

        ' Wait on the event, and hold it until the program
        ' exits.
        '
        Try
            Console.WriteLine("Wait on the event.")
            ewh.WaitOne()
            Console.WriteLine("Event was signaled.")
            Console.WriteLine("Press the Enter key to signal the event and exit.")
            Console.ReadLine()
        Catch ex As UnauthorizedAccessException
            Console.WriteLine("Unauthorized access: {0}", _
                ex.Message)
        Finally
            ewh.Set()
        End Try
    End Sub 
End Class

注解

使用此构造函数在创建命名系统事件时将访问控制安全性应用于该事件,从而阻止其他代码控制该事件。

此构造函数初始化表示 EventWaitHandle 系统事件的 对象。 可以创建表示同一系统事件的多个 EventWaitHandle 对象。

如果系统事件不存在,则会使用指定的访问控制安全性创建它。 如果该事件存在,则忽略指定的访问控制安全性。

注意

调用方可以完全控制新创建 EventWaitHandle 的对象,即使 eventSecurity 拒绝或未能向当前用户授予某些访问权限。 但是,如果当前用户尝试使用构造函数或 OpenExisting 方法获取另一个EventWaitHandle对象来表示同一命名事件,则会应用 Windows 访问控制安全性。

name可以使用 或 Local\ 作为Global\前缀,以指定命名空间。 Global指定命名空间后,可以与系统上的任何进程共享同步对象。 Local指定命名空间时(未指定命名空间时也是默认值),可以与同一会话中的进程共享同步对象。 在 Windows 上,会话是登录会话,服务通常在不同的非交互式会话中运行。 在类似于 Unix 的操作系统上,每个 shell 都有其自己的会话。 会话本地同步对象可能适合用于使用父/子关系(在这些进程都在同一会话中运行)之间进行同步。 有关 Windows 上的同步对象名称的详细信息,请参阅 对象名称

如果提供了 , name 并且命名空间中已存在请求类型的同步对象,则会打开现有的同步对象。 如果命名空间中已存在不同类型的同步对象, WaitHandleCannotBeOpenedException 则会引发 。 否则,将创建新的同步对象。

如果已存在具有为 name 参数指定名称的系统事件,则会忽略该 initialState 参数。 调用此构造函数后,使用为 Visual Basic createdNew) 中的参数 (ByRef 参数指定的ref变量中的值来确定命名系统事件是否已存在或已创建。

如果事件的初始状态未对齐,则等待事件的线程将阻塞。 如果发出初始状态信号,并且 ManualResetmode指定标志,则等待事件的线程不会阻止。 如果初始状态已发出信号,并且 modeAutoReset,则立即释放等待事件的第一个线程,然后事件将重置,后续线程将阻止。

注意

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

另请参阅

适用于