EventWaitHandle 建構函式
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
初始化 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) 使用 方法多載來允許主線程發出封鎖線程的訊號,然後等候線程完成工作。
此範例會啟動五個線程,並允許他們在使用 EventResetMode.AutoReset 旗標建立的 EventWaitHandle 上封鎖,然後每次使用者按下 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
備註
如果事件的初始狀態為未簽署,則等候事件的線程將會封鎖。 如果初始狀態已發出訊號,且 ManualReset 已為 mode
指定旗標,則等候事件的線程將不會封鎖。 如果初始狀態已發出訊號,且 mode
為 AutoReset,則會立即釋放等候事件的第一個線程,之後事件將會重設,而後續的線程將會封鎖。
另請參閱
適用於
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
的同步物件。 不同類型的同步物件可能具有相同名稱。
備註
name
前面可能會加上 Global\
或 Local\
,以指定命名空間。
Global
指定命名空間時,同步處理物件可能會與系統上的任何進程共用。
Local
指定命名空間時,這也是未指定命名空間時的預設值,同步處理物件可能會與相同會話中的進程共用。 在 Windows 上,會話是登入工作階段,服務通常會在不同的非互動式會話中執行。 在類似 Unix 的作業系統上,每個殼層都有自己的會話。 會話本機同步處理物件可能適用於在進程與父/子關聯性之間同步處理,其中它們全都在相同會話中執行。 如需 Windows 上同步處理物件名稱的詳細資訊,請參閱 物件名稱。
name
如果 已提供 ,且要求的型別同步處理物件已存在於命名空間中,則會開啟現有的同步處理物件。 如果命名空間中已經存在不同類型的同步處理物件, WaitHandleCannotBeOpenedException
則會擲回 。 否則,會建立新的同步處理物件。
如果為參數指定 name
名稱的系統事件已經存在,則會 initialState
忽略 參數。
警告
根據預設,具名事件不限於建立它的使用者。 其他使用者可以開啟和使用事件,包括藉由設定或不當重設事件來干擾事件。 若要限制特定使用者的存取權,您可以使用建構函式多載,或在 EventWaitHandleAcl 建立具名事件時傳入 EventWaitHandleSecurity 。 避免在執行程式代碼的系統上使用具名事件,而不受存取限制。
重要
針對具名系統事件使用此建構函式時,請針對 指定 false
initialState
。 這個建構函式無法判斷是否已建立具名系統事件,因此您無法對具名事件的狀態進行任何假設。 若要判斷是否已建立具名事件,請使用 EventWaitHandle(Boolean, EventResetMode, String, Boolean) 建構函式或建 EventWaitHandle(Boolean, EventResetMode, String, Boolean, EventWaitHandleSecurity) 構函式。
如果事件的初始狀態為未簽署,則等候事件的線程將會封鎖。 如果初始狀態已發出訊號,且 ManualReset 已為 mode
指定旗標,則等候事件的線程將不會封鎖。 如果初始狀態已發出訊號,且 mode
為 AutoReset,則會立即釋放等候事件的第一個線程,之後事件將會重設,而後續的線程將會封鎖。
另請參閱
適用於
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
這個方法傳回時,如果已建立本機事件 (也就是說,如果 name
為 true
或空字串),或是已建立指定的已命名系統事件,則會包含 null
;如果指定的已命名系統事件已存在則為 false
。 這個參數會以未初始化的狀態傳遞。
- 屬性
例外狀況
name
無效。 這可能基於數種原因,其中包括可能由作業系統設定的一些限制,例如未知前置詞或無效字元。 請注意,名稱和通用前置詞 「Global\」 和 「Local\」 會區分大小寫。
-或-
發生一些其他錯誤。
HResult
屬性可提供詳細資訊。
僅限 Windows:name
已指定未知命名空間。 請參閱物件名稱 \(英文\) 以取得詳細資訊。
name
太長。 長度限制可能會取決於作業系統或設定。
具名事件存在,並具有存取控制安全性,但使用者沒有 FullControl。
無法建立具有所提供 name
的同步物件。 不同類型的同步物件可能具有相同名稱。
備註
name
前面可能會加上 Global\
或 Local\
,以指定命名空間。
Global
指定命名空間時,同步處理物件可能會與系統上的任何進程共用。
Local
指定命名空間時,這也是未指定命名空間時的預設值,同步處理物件可能會與相同會話中的進程共用。 在 Windows 上,會話是登入工作階段,服務通常會在不同的非互動式會話中執行。 在類似 Unix 的作業系統上,每個殼層都有自己的會話。 會話本機同步處理物件可能適用於在進程與父/子關聯性之間同步處理,其中它們全都在相同會話中執行。 如需 Windows 上同步處理物件名稱的詳細資訊,請參閱 物件名稱。
name
如果 已提供 ,且要求的型別同步處理物件已存在於命名空間中,則會開啟現有的同步處理物件。 如果命名空間中已經存在不同類型的同步處理物件, WaitHandleCannotBeOpenedException
則會擲回 。 否則,會建立新的同步處理物件。
如果為參數指定 name
名稱的系統事件已經存在,則會 initialState
忽略 參數。 呼叫這個建構函式之後,請使用 Visual Basic 中為 ref
參數指定之變數中的值 (ByRef
參數) , createdNew
以判斷具名系統事件是否已存在或已建立。
如果事件的初始狀態為未簽署,則等候事件的線程將會封鎖。 如果初始狀態已發出訊號,且 ManualReset 已為 mode
指定旗標,則等候事件的線程將不會封鎖。 如果初始狀態已發出訊號,且 mode
為 AutoReset,則會立即釋放等候事件的第一個線程,之後事件將會重設,而後續的線程將會封鎖。
警告
根據預設,具名事件不限於建立它的使用者。 其他使用者可以開啟和使用事件,包括藉由設定或不當重設事件來干擾事件。 若要限制特定使用者的存取權,您可以使用建構函式多載,或在 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
這個方法傳回時,如果已建立本機事件 (也就是說,如果 name
為 true
或空字串),或是已建立指定的已命名系統事件,則會包含 null
;如果指定的已命名系統事件已存在則為 false
。 這個參數會以未初始化的狀態傳遞。
- eventSecurity
- EventWaitHandleSecurity
EventWaitHandleSecurity 物件,代表要套用至具名系統事件的存取控制安全性。
- 屬性
例外狀況
name
無效。 這可能基於數種原因,其中包括可能由作業系統設定的一些限制,例如未知前置詞或無效字元。 請注意,名稱和通用前置詞 「Global\」 和 「Local\」 會區分大小寫。
-或-
發生一些其他錯誤。
HResult
屬性可提供詳細資訊。
僅限 Windows:name
已指定未知命名空間。 請參閱物件名稱 \(英文\) 以取得詳細資訊。
name
太長。 長度限制可能會取決於作業系統或設定。
具名事件存在,並具有存取控制安全性,但使用者沒有 FullControl。
無法建立具有所提供 name
的同步物件。 不同類型的同步物件可能具有相同名稱。
範例
下列程式代碼範例示範具名系統事件具有訪問控制安全性的跨進程行為。 此範例會 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 物件。
如果系統事件不存在,則會使用指定的訪問控制安全性來建立它。 如果事件存在,則會忽略指定的訪問控制安全性。
注意
即使eventSecurity
拒絕或無法將某些訪問許可權授與目前使用者,呼叫端仍可完全控制新建立EventWaitHandle的物件。 不過,如果目前用戶嘗試取得另一個 EventWaitHandle 物件來表示相同的具名事件,請使用建構函式或 OpenExisting 方法,套用 Windows 存取控制安全性。
name
前面可能會加上 Global\
或 Local\
,以指定命名空間。
Global
指定命名空間時,同步處理物件可能會與系統上的任何進程共用。
Local
指定命名空間時,這也是未指定命名空間時的預設值,同步處理物件可能會與相同會話中的進程共用。 在 Windows 上,會話是登入工作階段,服務通常會在不同的非互動式會話中執行。 在類似 Unix 的作業系統上,每個殼層都有自己的會話。 會話本機同步處理物件可能適用於在進程與父/子關聯性之間同步處理,其中它們全都在相同會話中執行。 如需 Windows 上同步處理物件名稱的詳細資訊,請參閱 物件名稱。
name
如果 已提供 ,且要求的型別同步處理物件已存在於命名空間中,則會開啟現有的同步處理物件。 如果命名空間中已經存在不同類型的同步處理物件, WaitHandleCannotBeOpenedException
則會擲回 。 否則,會建立新的同步處理物件。
如果為參數指定 name
名稱的系統事件已經存在,則會 initialState
忽略 參數。 呼叫這個建構函式之後,請使用 Visual Basic 中為 ref
參數指定之變數的值 (ByRef
參數, createdNew
) 判斷具名系統事件是否已存在或已建立。
如果事件的初始狀態為未簽署,則等候事件的線程將會封鎖。 如果初始狀態已發出訊號,且 ManualReset 已為 mode
指定旗標,則等候事件的線程將不會封鎖。 如果初始狀態已發出訊號,且 mode
為 AutoReset,則會立即釋放等候事件的第一個線程,之後事件將會重設,而後續的線程將會封鎖。
警告
根據預設,具名事件不限於建立它的使用者。 其他使用者可以開啟和使用事件,包括藉由設定或不當重設事件來干擾事件。 若要限制特定使用者的存取權,您可以在建立具名事件時傳入 EventWaitHandleSecurity 。 避免在執行程式代碼的系統上使用具名事件,而不受存取限制。