C# ManualResetEventSlim

Resumo : neste tutorial, você aprenderá como usar C# ManualResetEventSlimpara fornecer uma maneira de os threads se comunicarem entre si.

Introdução à classe C# ManualResetEventSlim

A ManualResetEventSlimclasse permite que threads esperem por um sinal de outro thread antes de continuar a execução. Em outras palavras, a ManualResetEventSlimclasse permite sincronizar a execução de vários threads.

Como um AutoResetEventobjeto, um ManualResetEventSlimobjeto possui dois estados:

  • Sinalizado
  • Não sinalizado

A ManualResetEventSlimclasse é chamada de “Manual” porque uma vez sinalizado o evento, ele permanece sinalizado até que seja reiniciado manualmente.

Além disso, a ManualResetEventSlimclasse é chamada de “Slim” porque é uma implementação leve da ManualResetEventclasse. O ManualResetEventSlimé otimizado para desempenho e usa menos memória que a ManualResetEventclasse.

Para usar a ManualResetEventSlimclasse, siga estas etapas:

Primeiro, crie um novo ManualResetEventSlimobjeto:

var resetEvent = new ManualResetEventSlim(false);Linguagem de código:  JavaScript  ( javascript )

O falseargumento, 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 ManualResetEventSlimobjeto:

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 ManualResetEventSlimobjeto.

Quinto, chame o Reset()método do ManualResetEventSlimobjeto 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 ManualResetEventSlimclasse 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 ManualResetEventSlimobjeto 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 ManualResetEventSLimobjeto para aguardar a sinalização do evento.

O Wait()método bloqueia os threads que executam o DoWork()método até que o ManualResetEventSlimobjeto seja sinalizado.

Quando for ManualResetEventSlimsinalizado, o método retoma sua execução que grava outra mensagem no console.

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 ManualEventResetSlimobjeto a ser sinalizado chamando seu 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 ManualResetEventclasse C# para representar um evento de sincronização de thread que permite que um ou mais threads aguardem a ocorrência do evento.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *