Pergunta

Ambos parecem cumprir a mesma finalidade. Quando eu escolheria um sobre o outro?

Foi útil?

Solução

Use os eventos quando você tem um segmento que está esperando em um dos ou todos de uma série de eventos para fazer alguma coisa.

Use o monitor se você quiser restringir o acesso a uma estrutura de dados, limitando quantos segmentos podem acessá-lo.

Monitores geralmente proteger um recurso, ao passo que os eventos lhe dizer acontecimento de algo, como a aplicação a ser encerrado.

Além disso, os eventos podem ser nomeados (veja o método OpenExisting), o que lhes permite ser usado para sincronização através de processos diferentes.

Outras dicas

Na minha opinião, é melhor usar o Monitor se você pode, Monitor.Wait e Monitor.Pulse / PulseAll são usados ??para sinalização entre segmentos (como são Manual / AutoResetEvent) no entanto Monitor é mais rápido, e não usa um nativo recursos do sistema. Além disso, aparentemente, Monitor é implementado no modo de usuário e é gerido, enquanto / AutoResetEvents manuais exigem mudar para o modo kernel e p / chamar para chamadas Win32 nativas que usam um identificador de espera.

Há situações em que você precisa para usar Manual / AutoResetEvent, por exemplo, para sinalizar entre os processos que você pode usar eventos nomeados, e eu acho que para sinalizar threads nativas em seu aplicativo.

Estou apenas regurgitar o que eu li na este excelente artigo cerca de enfiar.

Todo o artigo vale a pena ler, no entanto, o link leva você para a seção identificador de espera que detalha a eventos e monitor de espera / pulso.

Você usaria um WaitHandle quando você quer um fio para enviar ou receber um sinal binário sem a necessidade de uma seção crítica. Monitor.Wait e Monitor.Pulse por outro lado requerem uma seção crítica. Como a maioria dos mecanismos de sincronização no BCL haja alguma sobreposição na forma como um dos dois que você mencionou pode ser usado. Mas, não pense por um momento que eles cumprem a mesma finalidade.

Monitor.Wait e Monitor.Pulse são um mecanismo de sincronização muito mais primitivos do que um MRE ou SÃO. Na verdade, você pode realmente construir uma MRE ou está usando nada mais do que a classe Monitor. O conceito mais importante a entender é como os métodos Monitor.Wait e WaitHandle.WaitOne diferem. Wait e WaitOne vai colocar tanto o segmento no estado WaitSleepJoin o que significa que o fio se torna inativo e só responde a qualquer um Thread.Interrupt ou a respectiva chamada Pulse ou Set. Mas, e isso é uma grande diferença, Wait vai deixar uma seção crítica e readquiri-la de uma maneira atômica . WaitOne simplesmente não pode fazer isso. É uma diferença tão fundamental para a forma como estes mecanismos de sincronização comportam dessa define os cenários em que eles podem ser usados.

Na maioria das situações você escolheria uma MRE ou estão. Estes satisfazer a maioria das situações em que um segmento precisa receber um sinal de outro. No entanto, se você quiser criar o seu próprio mecanismo de sinalização, então você precisa usar Wait e Pulse. Mas, novamente, o .NET BCL tem a maioria dos mecanismos de sinalização populares já coberto. Os mecanismos de sinalização seguinte já existem 1 .

  • ManualResetEvent (ou ManualResetEventSlim)
  • AutoResetEvent
  • Semaphore (ou SemaphoreSlim)
  • EventWaitHandle
  • CountdownEvent
  • Barreira

1 Uma menção honrosa vai para a classe BlockingCollection. Não é um mecanismo de sinalização, por si só, mas ele tem as qualidades de um mecanismo de sinalização com o benefício adicional que você pode anexar dados para o sinal. Neste caso, os meios de sinal que um item está disponível na coleta e os dados associados com esse sinal é o item em si.

Este tutorial tem descrições detalhadas do que você precisa saber: http://www.albahari.com/threading/

Em particular, este irá cobrir as classes XXXResetEvent,
http://www.albahari.com/threading/part2.aspx

e isso irá cobrir Wait / Pulse: http://www.albahari.com/threading/part4.aspx#_Wait_and_Pulse

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top