EventWaitHandleEventWaitHandle

A classe EventWaitHandle permite que os threads se comuniquem entre si por meio da sinalização e aguardando sinais.The EventWaitHandle class allows threads to communicate with each other by signaling and by waiting for signals. Identificadores de espera de eventos (conhecidos simplesmente como eventos) são identificadores de espera que podem ser sinalizados a fim de liberar um ou mais threads de espera.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. Após a sinalização, um identificador de espera de eventos é redefinido manualmente ou automaticamente.After it is signaled, an event wait handle is reset either manually or automatically. A classe EventWaitHandle pode representar um identificador de espera de evento local (evento local) ou um identificador de espera evento de evento do sistema nomeado (evento nomeado ou evento do sistema, visível a todos os processos).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).

Observação

Os identificadores de espera de eventos não são eventos do .NET.Event wait handles are not .NET events. Não há delegados ou manipuladores de eventos envolvidos.There are no delegates or event handlers involved. A palavra "evento" é usada para descrevê-los, pois eles têm sido chamados tradicionalmente de eventos do sistema operacional, e porque o ato de sinalização do identificador de espera indica aos threads de espera que um evento ocorreu.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.

Os identificadores de espera de eventos local e nomeado usam objetos de sincronização do sistema, que são protegidos por wrappers SafeWaitHandle a fim de garantir a liberação de recursos.Both local and named event wait handles use system synchronization objects, which are protected by SafeWaitHandle wrappers to ensure that the resources are released. Você pode usar o método Dispose para liberar os recursos imediatamente ao terminar de usar o objeto.You can use the Dispose method to free the resources immediately when you have finished using the object.

Identificadores de espera de eventos redefinidos automaticamenteEvent Wait Handles That Reset Automatically

Crie um evento de redefinição automática especificando EventResetMode.AutoReset ao criar o objeto EventWaitHandle.You create an automatic reset event by specifying EventResetMode.AutoReset when you create the EventWaitHandle object. Como o nome sugere, esse evento de sincronização é redefinido automaticamente quando sinalizado, após a liberação de um thread de espera único.As its name implies, this synchronization event resets automatically when signaled, after releasing a single waiting thread. Sinalize o evento chamando seu método Set.Signal the event by calling its Set method.

Os eventos de redefinição automática geralmente são usados para fornecer acesso exclusivo a um recurso para um thread por vez.Automatic reset events are usually used to provide exclusive access to a resource for a single thread at a time. Um thread solicita o recurso chamando o método WaitOne.A thread requests the resource by calling the WaitOne method. Se nenhum outro thread estiver usando o identificador de espera, o método retornará true, e o thread de chamada terá o controle do recurso.If no other thread is holding the wait handle, the method returns true and the calling thread has control of the resource.

Importante

Assim como ocorre com todos os mecanismos de sincronização, você deve garantir que todos os caminhos de código aguardem o identificador de espera apropriado antes de acessar um recurso protegido.As with all synchronization mechanisms, you must ensure that all code paths wait on the appropriate wait handle before accessing a protected resource. A sincronização do thread é cooperativa.Thread synchronization is cooperative.

Se um evento de redefinição automática for sinalizado quando não houver threads em espera, ele permanecerá sinalizado até que um thread tente esperar por ele.If an automatic reset event is signaled when no threads are waiting, it remains signaled until a thread attempts to wait on it. O evento libera o thread e redefine imediatamente, bloqueando os threads subsequentes.The event releases the thread and immediately resets, blocking subsequent threads.

Identificadores de espera de evento redefinidos automaticamenteEvent Wait Handles That Reset Manually

Crie um evento de redefinição manual especificando EventResetMode.ManualReset ao criar o objeto EventWaitHandle.You create a manual reset event by specifying EventResetMode.ManualReset when you create the EventWaitHandle object. Como o nome sugere, esse evento de sincronização deve ser redefinido manualmente após a sinalização.As its name implies, this synchronization event must be reset manually after it has been signaled. Até a redefinição, ao chamar seu método Reset, os threads que aguardam o identificador de evento continuam imediatamente sem bloqueio.Until it is reset, by calling its Reset method, threads that wait on the event handle proceed immediately without blocking.

Um evento de redefinição manual age como a porta de um curral.A manual reset event acts like the gate of a corral. Quando o evento não é sinalizado, os threads que aguardam por ele ficam bloqueados, como cavalos em um curral.When the event is not signaled, threads that wait on it block, like horses in a corral. Quando o evento é sinalizado, ao chamar seu método Set, todos os threads em espera ficam livres para continuar.When the event is signaled, by calling its Set method, all waiting threads are free to proceed. O evento permanece sinalizado até que seu método Reset seja chamado.The event remains signaled until its Reset method is called. Isso torna o evento de redefinição manual a maneira ideal de armazenar threads que precisam aguardar até que um thread conclua uma tarefa.This makes the manual reset event an ideal way to hold up threads that need to wait until one thread finishes a task.

Como cavalos deixando um curral, demora até o sistema operacional agendar os threads liberados e continuar a execução.Like horses leaving a corral, it takes time for the released threads to be scheduled by the operating system and to resume execution. Se o método Reset for chamado antes de todos os threads voltarem a operar, os threads restantes serão bloqueados novamente.If the Reset method is called before all the threads have resumed execution, the remaining threads once again block. Os threads que retomam a operação e os threads que são bloqueados depende de fatores aleatórios, como a carga no sistema, o número de threads aguardando o agendador etc.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. Isso não será um problema se o thread que sinaliza o evento terminar após a sinalização, o que é o padrão de uso mais comum.This is not a problem if the thread that signals the event ends after signaling, which is the most common usage pattern. Se você quiser que o thread que sinalizou o evento comece uma nova tarefa após a continuação de todos threads em espera, você deverá bloqueá-lo até que todos os threads em espera tenham retomado a ação.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. Caso contrário, você terá uma condição de corrida, e o comportamento do seu código será imprevisível.Otherwise, you have a race condition, and the behavior of your code is unpredictable.

Recursos comuns a eventos automáticos e manuaisFeatures Common to Automatic and Manual Events

Normalmente, um ou mais threads ficam bloqueados em um EventWaitHandle até que um thread desbloqueado chame o método Set, o que libera um dos threads em espera (no caso de eventos de redefinição automática) ou todos eles (no caso de eventos de redefinição manual).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). Um thread pode sinalizar um EventWaitHandle e depois bloqueá-lo, como uma operação atômica, chamando o método WaitHandle.SignalAndWait estático.A thread can signal an EventWaitHandle and then block on it, as an atomic operation, by calling the static WaitHandle.SignalAndWait method.

Os objetos EventWaitHandle podem ser usados com os métodos WaitHandle.WaitAll e WaitHandle.WaitAny estáticos.EventWaitHandle objects can be used with the static WaitHandle.WaitAll and WaitHandle.WaitAny methods. Como as classes EventWaitHandle e Mutex derivam de WaitHandle, você pode usar as duas classes com esses métodos.Because the EventWaitHandle and Mutex classes both derive from WaitHandle, you can use both classes with these methods.

Eventos nomeadosNamed Events

O sistema operacional Windows permite que os identificadores de espera de evento tenham nomes.The Windows operating system allows event wait handles to have names. Um evento nomeado serve para todo o sistema.A named event is system wide. Ou seja, após a criação de um evento nomeado, ele fica visível para todos os threads em todos os processos.That is, once the named event is created, it is visible to all threads in all processes. Assim, os eventos nomeados podem ser usados para sincronizar as atividades de processos, bem como os threads.Thus, named events can be used to synchronize the activities of processes as well as threads.

Você pode criar um objeto EventWaitHandle que representa um evento de sistema nomeado usando um dos construtores que especifica um nome de evento.You can create an EventWaitHandle object that represents a named system event by using one of the constructors that specifies an event name.

Observação

Como os eventos nomeados servem para todo o sistema, é possível ter vários objetos EventWaitHandle que representam o mesmo evento nomeado.Because named events are system wide, it is possible to have multiple EventWaitHandle objects that represent the same named event. Cada vez que você chama um construtor ou o método OpenExisting, um novo objeto EventWaitHandle é criado.Each time you call a constructor, or the OpenExisting method, a new EventWaitHandle object is created. Especificar o mesmo nome repetidas vezes cria vários objetos que representam o mesmo evento nomeado.Specifying the same name repeatedly creates multiple objects that represent the same named event.

Tenha cuidado ao usar eventos nomeados.Caution is advised in using named events. Como eles servem para todo o sistema, outro processo que usa o mesmo nome pode bloquear seus threads inesperadamente.Because they are system wide, another process that uses the same name can block your threads unexpectedly. Código mal-intencionado em execução no mesmo computador pode usar isso como base de um ataque de negação de serviço.Malicious code executing on the same computer could use this as the basis of a denial-of-service attack.

Use a segurança de controle de acesso para proteger um objeto EventWaitHandle que representa um evento nomeado, preferencialmente usando um construtor que especifica um objeto 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. Também é possível aplicar a segurança de controle de acesso usando o método SetAccessControl, mas isso deixa uma janela de vulnerabilidade entre o momento em que o identificador em espera de evento é criado e o momento em que ele é protegido.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. Proteger eventos com a segurança de controle de acesso ajuda a impedir ataques mal-intencionados, mas não resolve o problema de colisão de nome não intencional.Protecting events with access control security helps prevent malicious attacks, but it does not solve the problem of unintentional name collisions.

Observação

Ao contrário da classe EventWaitHandle, as classes derivadas AutoResetEvent e ManualResetEvent podem representar somente identificadores em espera locais.Unlike the EventWaitHandle class, the derived classes AutoResetEvent and ManualResetEvent can represent only local wait handles. Eles não podem representar eventos nomeados do sistema.They cannot represent named system events.

Confira tambémSee also