Israel Aéce

Microsoft MVP, MCP, MCAD, MCTS, MCPD e MCT

My Links

Blog Stats

Archives

Post Categories

Links

Login

ManualResetEvent vs. AutoResetEvent

Ambas as classes que são temas do post tem basicamente a mesma finalidade, ou seja, efetuar a sinalização entre threads. Isso permite que uma determinada thread notifique as outras threads que ela finalizou ou liberou um determinado recurso e, conseqüentemente, essas outras threads poderão dar seqüencia na execução.

Leve em consideração o seguinte código:

delegate void Executor();

private static XXX _resetEvent = new XXX(false);

static void Main(string[] args)
{
    new Executor(Teste1).BeginInvoke(null, null);
    new Executor(Teste2).BeginInvoke(null, null);
    new Executor(Teste3).BeginInvoke(null, null);

    Console.WriteLine("Fim");
    Console.ReadLine();
}

static void Teste1()
{
    Console.WriteLine("Teste1 - Antes");

    Thread.Sleep(5000); //Simula um processamento pesado
    _resetEvent.Set();
   
    Console.WriteLine("Teste1 - Depois");
}

static void Teste2()
{
    Console.WriteLine("Teste2 - Antes");
    _resetEvent.WaitOne();
    Console.WriteLine("Teste2 - Depois");
}

static void Teste3()
{
    Console.WriteLine("Teste3 - Antes");
    _resetEvent.WaitOne();
    Console.WriteLine("Teste3 - Depois");
}

Resultados para quando XXX = ManualResetEvent
Fim
Teste1 - Antes
Teste2 - Antes
Teste3 - Antes
Teste1 - Depois
Teste3 - Depois
Teste2 - Depois

Resultados para quando XXX = AutoResetEvent
Fim
Teste1 - Antes
Teste2 - Antes
Teste3 - Antes
Teste1 - Depois
Teste3 - Depois

Como sabemos, o método BeginInvoke fornecido pela instancia do delegate permite a chamado para o método que ele aponta de forma assíncrona, ou seja, será criada uma worker thread para cada um deles; sendo assim, os processos acontecerão paralelamente e o reset event está aqui para garantir a sincronização das informações, ou melhor, destes métodos.

Quando utilizamos o método WaitOne do ManualResetEvent nos métodos 2 e 3, eles aguardarão um sinal que, por sua vez, será dado através do método Set, também do ManualResetEvent. Enquanto isso não acontecer, os métodos 2 e 3 não darão sequencia no processamento. Se repararmos o resultado final, as mensagens (writelines) que a aparecem depois do método WaitOne retornará, isso quer dizer que ele ficará "travado" até receber o sinal para prosseguir. Uma vez recebido, todos aqueles que estiveremos pendentes serão executados.

Já com um AutoResetEvent, o processo é muito semelhante, com a exceção que quando o método Set for chamado, apenas uma thread da fila será executada. Isso explica o motivo pelo qual a mensagem do método 2 ("Teste2 - Depois") não aparece no resultado final.

Bem, isso é uma das N possibilidades que o .NET fornece para efetuar a sincronização através de sinalização. Para aqueles que querem se aprofundar, vejam o namespace System.Threading.

posted on Tuesday, May 20, 2008 6:03 PM

Feedback

# re: ManualResetEvent vs. AutoResetEvent 5/23/2008 4:58 PM Luis Abreu

Israel, ja agora, ja deste olhadela as parallel extensions?

# re: ManualResetEvent vs. AutoResetEvent 5/26/2008 4:06 AM Israel Aece

Ola Luis,

Superficialmente, até porque não tinha hardware para ver o real benefício. Agora que comprei um notebook Core 2 Duo, acredito que será possível fazer alguns testes.

Assisti uma palestra no MVP Summit e pude notar o grande benefício que isso traz. É incrível ver, inicialmente, a afinidade que uma determinada tarefa causa com um processador e, em seguida, utilizando esta Library todos os processadores entrando em cena e fazendo um pouco do trabalho.

# Anothr feed track -Israel Aéce 5/26/2008 11:30 PM anothr user

One new subscriber from Anothr Alerts

Title  
Name  
Url
Box Code
Protected by FormShield
Comments