Resumo : neste tutorial, você aprenderá como usar C# ManualResetEventSlim
para fornecer uma maneira de os threads se comunicarem entre si.
Introdução à classe C# ManualResetEventSlim
A ManualResetEventSlim
classe permite que threads esperem por um sinal de outro thread antes de continuar a execução. Em outras palavras, a ManualResetEventSlim
classe permite sincronizar a execução de vários threads.
Como um AutoResetEvent
objeto, um ManualResetEventSlim
objeto possui dois estados:
- Sinalizado
- Não sinalizado
A ManualResetEventSlim
classe é chamada de “Manual” porque uma vez sinalizado o evento, ele permanece sinalizado até que seja reiniciado manualmente.
Além disso, a ManualResetEventSlim
classe é chamada de “Slim” porque é uma implementação leve da ManualResetEvent
classe. O ManualResetEventSlim
é otimizado para desempenho e usa menos memória que a ManualResetEvent
classe.
Para usar a ManualResetEventSlim
classe, siga estas etapas:
Primeiro, crie um novo ManualResetEventSlim
objeto:
var resetEvent = new ManualResetEventSlim(false);
Linguagem de código: JavaScript ( javascript )
O false
argumento, que passamos ao construtor, define o estado inicial do evento como não sinalizado.
Segundo, crie um ou mais threads que aguardam a sinalização do evento:
var t = new Thread(() => {
// do some work
// ...
// wait for the event to be signaled
resetEvent.Wait();
// continue the execution after the event is signaled
});
Linguagem de código: JavaScript ( javascript )
O Wait()
método bloqueará os threads em espera até que o evento seja sinalizado.
Terceiro, inicie o tópico:
t.Start();
Linguagem de código: CSS ( css )
Quarto, sinalize o evento chamando o Set()
método no ManualResetEventSlim
objeto:
resetEvent.Set();
Linguagem de código: CSS ( css )
O Set()
método libera todas as threads que aguardam o evento para retomar suas execuções até que o próximo Reset()
método seja chamado no ManualResetEventSlim
objeto.
Quinto, chame o Reset()
método do ManualResetEventSlim
objeto para redefinir o estado para não sinalizado, o que bloqueia todos os threads em espera:
resetEvent.Reset();
Linguagem de código: CSS ( css )
Exemplo C# ManualResetEventSlim
O programa a seguir demonstra como a ManualResetEventSlim
classe funciona:
using static System.Console;
var resetEvent = new ManualResetEventSlim(false);
void DoWork()
{
WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} is waiting for the event to be signaled...");
// Wait for the event to be signaled
resetEvent.Wait();
WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} has been signaled and has resumed execution.");
}
// Create a thread that wait for the event to be signaled and start it
var t1 = new Thread(() => DoWork());
var t2 = new Thread(() => DoWork());
t1.Start();
t2.Start();
// Wait for 1s to let the thread runs for a while
Thread.Sleep(1000);
// Wait for 2s before signaling the event
WriteLine("Waiting for 2 seconds before signaling the event...");
Thread.Sleep(2000);
// Signal the event
resetEvent.Set();
// Wait for the threads to finish
t1.Join();
t2.Join();
WriteLine("Press any key to exit.");
ReadKey();
Linguagem de código: JavaScript ( javascript )
Saída:
Thread 10 is waiting for the event to be signaled...
Thread 11 is waiting for the event to be signaled...
Waiting for 2 seconds before signaling the event...
Thread 11 has been signaled and has resumed execution.
Thread 10 has been signaled and has resumed execution.
Press any key to exit.
Linguagem de código: PHP ( php )
Como funciona.
Primeiro, crie um novo ManualResetEventSlim
objeto e inicialize-o com false
, indicando que o evento não está sinalizado inicialmente:
var resetEvent = new ManualResetEventSlim(false);
Linguagem de código: JavaScript ( javascript )
Segundo, defina o DoWork()
método que os threads em espera executarão:
void DoWork()
{
WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} is waiting for the event to be signaled...");
// Wait for the event to be signaled
resetEvent.Wait();
WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} has been signaled and has resumed execution.");
}
Linguagem de código: JavaScript ( javascript )
O DoWork()
método grava uma mensagem no console indicando que a thread está aguardando a sinalização do evento. Em seguida, ele chama o Wait()
método do ManualResetEventSLim
objeto para aguardar a sinalização do evento.
O Wait()
método bloqueia os threads que executam o DoWork()
método até que o ManualResetEventSlim
objeto seja sinalizado.
Quando for
sinalizado, o método retoma sua execução que grava outra mensagem no console.ManualResetEventSlim
Terceiro, crie dois threads que executem o DoWork()
método e inicie-os imediatamente:
// Create threads that wait for the event to be signaled and start them
var t1 = new Thread(() => DoWork());
var t2 = new Thread(() => DoWork());
t1.Start();
t2.Start();
Linguagem de código: JavaScript ( javascript )
Quarto, espere um segundo para deixar tempo suficiente para que os threads sejam executados até que o Wait()
método seja chamado:
Thread.Sleep(1000);
Linguagem de código: CSS ( css )
Quinto, escreva uma mensagem no console e aguarde dois segundos antes de sinalizar o evento:
WriteLine("Waiting for 2 seconds before signaling the event...");
Thread.Sleep(2000);
Linguagem de código: JavaScript ( javascript )
Sexto, altere o estado do
objeto a ser sinalizado chamando seu ManualEventResetSlim
Set()
método:
// Signal the event
resetEvent.Set();
Linguagem de código: JavaScript ( javascript )
Após esta chamada, as threads que executam o DoWork()
método retomam suas execuções e exibem mensagens para o console.
Sétimo, aguarde a conclusão dos threads chamando o Join()
método:
// Wait for the threads to finish
t1.Join();
t2.Join();
Linguagem de código: JavaScript ( javascript )
Por fim, espere que o usuário pressione qualquer tecla para sair do programa:
WriteLine("Press any key to exit.");
ReadKey();
Linguagem de código: JavaScript ( javascript )
Resumo
- Use uma
ManualResetEvent
classe C# para representar um evento de sincronização de thread que permite que um ou mais threads aguardem a ocorrência do evento.