EventWaitHandleEventWaitHandle

EventWaitHandle クラスを使用すると、スレッドは通知および通知の待機により、互いに通信できます。The EventWaitHandle class allows threads to communicate with each other by signaling and by waiting for signals. イベント待機ハンドル (単にイベントとも呼ばれます) は、通知を受けて、1 つ以上の待機中のイベントを解放できる待機ハンドルです。Event wait handles (also referred to simply as events) are wait handles that can be signaled in order to release one or more waiting threads. 通知を受けると、イベント待機ハンドルは手動または自動でリセットされます。After it is signaled, an event wait handle is reset either manually or automatically. EventWaitHandle クラスは、ローカルのイベント待機ハンドル (ローカル イベント) または名前付きのシステム イベント待機ハンドル (名前付きのイベントまたはシステム イベント。すべてのプロセスから参照できます) を表すことができます。The EventWaitHandle class can represent either a local event wait handle (local event) or a named system event wait handle (named event or system event, visible to all processes).

注意

イベント待機ハンドルは、通常 .NET Framework でイベントと呼ばれるものとは異なります。Event wait handles are not events in the sense usually meant by that word in the .NET Framework. デリゲートやイベント ハンドラーは関連していません。There are no delegates or event handlers involved. "イベント" という言葉で説明されているのは、それらがこれまでオペレーティング システム イベントと呼ばれており、待機ハンドルの通知はイベントが発生した待機中のスレッドを示すためです。The word "event" is used to describe them because they have traditionally been referred to as operating-system events, and because the act of signaling the wait handle indicates to waiting threads that an event has occurred.

ローカル イベント待機ハンドルと名前付きイベント待機ハンドルはどちらも、システム同期オブジェクトを使用します。これは SafeWaitHandle ラッパーによって保護されており、リソースが確実に解放されるようにします。Both local and named event wait handles use system synchronization objects, which are protected by SafeWaitHandle wrappers to ensure that the resources are released. Dispose メソッドを使用すると、オブジェクトを使い終わったらすぐにリソースを解放できます。You can use the Dispose method to free the resources immediately when you have finished using the object.

自動的にリセットされるイベント待機ハンドルEvent Wait Handles That Reset Automatically

自動リセット イベントを作成するには、EventWaitHandle オブジェクトを作成するときに EventResetMode.AutoReset を指定します。You create an automatic reset event by specifying EventResetMode.AutoReset when you create the EventWaitHandle object. その名前が示すとおり、この同期イベントは通知を受けたときに、単一の待機中のスレッドを解放した後、自動的にリセットされます。As its name implies, this synchronization event resets automatically when signaled, after releasing a single waiting thread. イベントを通知するには、その Set メソッドを呼び出します。Signal the event by calling its Set method.

通常、自動リセット イベントは、単一のスレッドのリソースに一度に排他アクセスを提供するために使用されます。Automatic reset events are usually used to provide exclusive access to a resource for a single thread at a time. スレッドは、WaitOne メソッドを呼び出してリソースを要求します。A thread requests the resource by calling the WaitOne method. 他のスレッドに待機ハンドルがない場合、メソッドは true を返し、呼び出し元スレッドはリソースの制御権を持ちます。If no other thread is holding the wait handle, the method returns true and the calling thread has control of the resource.

重要

あらゆる同期機構と同様に、すべてのコード パスが適切な待機ハンドルを待ってから、保護されているリソースにアクセスする必要があります。As with all synchronization mechanisms, you must ensure that all code paths wait on the appropriate wait handle before accessing a protected resource. スレッドの同期は連携しています。Thread synchronization is cooperative.

自動リセット イベントが通知を受けたとき、待機中のスレッドがない場合は、スレッドが待機中になるまでシグナル状態のままです。If an automatic reset event is signaled when no threads are waiting, it remains signaled until a thread attempts to wait on it. イベントはスレッドを解放してすぐにリセットされ、以降のスレッドをブロックします。The event releases the thread and immediately resets, blocking subsequent threads.

手動でリセットされるイベント待機ハンドルEvent Wait Handles That Reset Manually

手動リセット イベントを作成するには、EventWaitHandle オブジェクトを作成するときに EventResetMode.ManualReset を指定します。You create a manual reset event by specifying EventResetMode.ManualReset when you create the EventWaitHandle object. その名前が示すとおり、この同期イベントは、通知を受けた後に手動でリセットする必要があります。As its name implies, this synchronization event must be reset manually after it has been signaled. Reset メソッドを呼び出してリセットするまで、イベント ハンドルを待っているスレッドはすぐに続行され、ブロックされません。Until it is reset, by calling its Reset method, threads that wait on the event handle proceed immediately without blocking.

手動リセット イベントは、家畜を飼う囲いのゲートのように動作します。A manual reset event acts like the gate of a corral. イベントが通知を受けないと、待機中のスレッドは囲いの中の馬のようにブロックされます。When the event is not signaled, threads that wait on it block, like horses in a corral. イベントが通知を受けると、その Set メソッドを呼び出して、すべての待機中のスレッドは自由に続行できます。When the event is signaled, by calling its Set method, all waiting threads are free to proceed. イベントは、その Reset メソッドが呼び出されるまで、シグナル状態のままです。The event remains signaled until its Reset method is called. これにより、手動リセット イベントは、1 つのスレッドがタスクを終えるまで待機させる必要のあるスレッドを保持する理想的な方法となっています。This makes the manual reset event an ideal way to hold up threads that need to wait until one thread finishes a task.

馬が囲いから出るように、解放されたスレッドがオペレーティング システムによってスケジュールされ、実行が再開されるには時間がかかります。Like horses leaving a corral, it takes time for the released threads to be scheduled by the operating system and to resume execution. すべてのスレッドの実行が再開される前に Reset メソッドが呼び出された場合、残りのスレッドは再びブロックされます。If the Reset method is called before all the threads have resumed execution, the remaining threads once again block. 再開されるスレッドとブロックされるスレッドは、システム上の負荷や、スケジューラを待っているスレッドの数など、ランダムな要素によって異なります。Which threads resume and which threads block depends on random factors like the load on the system, the number of threads waiting for the scheduler, and so on. イベントを通知したスレッドが通知後に終了した場合 (これは最も一般的な使用パターンです)、これは問題ではありません。This is not a problem if the thread that signals the event ends after signaling, which is the most common usage pattern. すべての待機中のスレッドが再開された後で、イベントを通知したスレッドに新しいタスクを開始させる場合は、すべての待機中のスレッドが再開されるまで、そのスレッドをブロックする必要があります。If you want the thread that signaled the event to begin a new task after all the waiting threads have resumed, you must block it until all the waiting threads have resumed. それ以外の場合は競合状態で、コードの動作は予測できません。Otherwise, you have a race condition, and the behavior of your code is unpredictable.

自動イベントと手動イベントの共通の機能Features Common to Automatic and Manual Events

通常、ブロックされていないスレッドが Set メソッドを呼び出して、いずれかの待機中のスレッド (自動リセット イベントの場合) またはそれらすべて (手動リセット イベントの場合) を解放するまで、1 つ以上のスレッドが EventWaitHandle でブロックします。Typically, one or more threads block on an EventWaitHandle until an unblocked thread calls the Set method, which releases one of the waiting threads (in the case of automatic reset events) or all of them (in the case of manual reset events). スレッドは、静的な WaitHandle.SignalAndWait メソッドを呼び出すことにより、EventWaitHandle の通知とブロックを分割できない操作として行うことができます。A thread can signal an EventWaitHandle and then block on it, as an atomic operation, by calling the static WaitHandle.SignalAndWait method.

EventWaitHandle オブジェクトは、静的な WaitHandle.WaitAll および WaitHandle.WaitAny メソッドと共に使用できます。EventWaitHandle objects can be used with the static WaitHandle.WaitAll and WaitHandle.WaitAny methods. EventWaitHandle および Mutex クラスはいずれも WaitHandle から派生するため、両方のクラスをこれらのメソッドで使用できます。Because the EventWaitHandle and Mutex classes both derive from WaitHandle, you can use both classes with these methods.

名前付きのイベントNamed Events

Windows オペレーティング システムでは、イベント待機ハンドルに名前を付けることができます。The Windows operating system allows event wait handles to have names. 名前付きのイベントはシステム全体で使用されます。A named event is system wide. つまり、いったん名前付きのイベントを作成すると、すべてのプロセスのすべてのスレッドがそれを参照できます。That is, once the named event is created, it is visible to all threads in all processes. したがって、名前付きのイベントを使用して、スレッドだけでなくプロセスのアクティビティも同期できます。Thus, named events can be used to synchronize the activities of processes as well as threads.

名前付きのシステム イベントを表す EventWaitHandle オブジェクトを作成するには、イベントの名前を指定するいずれかのコンストラクターを使用します。You can create an EventWaitHandle object that represents a named system event by using one of the constructors that specifies an event name.

注意

名前付きのイベントはシステム全体で使用されるため、複数の EventWaitHandle オブジェクトで同じ名前付きイベントを表すことができます。Because named events are system wide, it is possible to have multiple EventWaitHandle objects that represent the same named event. コンストラクターまたは OpenExisting メソッドを呼び出すたびに、新しい EventWaitHandle オブジェクトが作成されます。Each time you call a constructor, or the OpenExisting method, a new EventWaitHandle object is created. 同じ名前を繰り返し指定すると、同じ名前付きイベントを表す複数のオブジェクトを作成できます。Specifying the same name repeatedly creates multiple objects that represent the same named event.

名前付きのイベントを使用する際には注意が必要です。Caution is advised in using named events. それらはシステム全体で使用されるので、別のプロセスが同じ名前を使用すると、スレッドが予期せずにブロックされる場合があります。Because they are system wide, another process that uses the same name can block your threads unexpectedly. 同じコンピューター上で実行される悪意のあるコードが、これをサービス拒否攻撃の土台として使用する可能性があります。Malicious code executing on the same computer could use this as the basis of a denial-of-service attack.

アクセス制御セキュリティを使用して、名前付きのイベントを表す EventWaitHandle オブジェクトを保護します。可能であれば EventWaitHandleSecurity オブジェクトを指定するコンストラクターを使用します。Use access control security to protect an EventWaitHandle object that represents a named event, preferably by using a constructor that specifies an EventWaitHandleSecurity object. また、SetAccessControl メソッドを使用してアクセス制御セキュリティを適用できますが、この場合、イベント待機ハンドルが作成されてから保護されるまでの間に無防備な時間帯が生じてしまいます。You can also apply access control security using the SetAccessControl method, but this leaves a window of vulnerability between the time the event wait handle is created and the time it is protected. アクセス制御セキュリティでイベントを保護すると、悪意のある攻撃を防ぐのに役立ちますが、予期しない名前の衝突の問題解決にはなりません。Protecting events with access control security helps prevent malicious attacks, but it does not solve the problem of unintentional name collisions.

注意

EventWaitHandle クラスとは異なり、派生したクラスである AutoResetEvent および ManualResetEvent は、ローカルの待機ハンドルのみを表すことができます。Unlike the EventWaitHandle class, the derived classes AutoResetEvent and ManualResetEvent can represent only local wait handles. 名前付きのシステム イベントを表すことはできません。They cannot represent named system events.

参照See Also

EventWaitHandle
WaitHandle
AutoResetEvent
ManualResetEvent
EventWaitHandle、AutoResetEvent、CountdownEvent、ManualResetEventEventWaitHandle, AutoResetEvent, CountdownEvent, ManualResetEvent