Quando dovrei usare AutoResetEvent e ManualResetEvent invece di Monitor.Wait () / Monitor.Pulse ()?

StackOverflow https://stackoverflow.com/questions/158133

Domanda

Entrambi sembrano soddisfare lo stesso scopo. Quando sceglierei uno sopra l'altro?

È stato utile?

Soluzione

Usa gli eventi quando hai un thread in attesa di uno o tutti gli eventi per fare qualcosa.

Utilizzare il monitor se si desidera limitare l'accesso a una struttura di dati limitando il numero di thread che possono accedervi.

I monitor di solito proteggono una risorsa, mentre gli eventi ti dicono che sta succedendo qualcosa, come la chiusura dell'applicazione.

Inoltre, gli eventi possono essere nominati (vedi il metodo OpenExisting), questo permette loro di essere usati per la sincronizzazione tra processi diversi.

Altri suggerimenti

A mio avviso, è meglio usare Monitor se possibile, Monitor.Wait e Monitor.Pulse / PulseAll sono utilizzati per la segnalazione tra thread (come Manual / AutoResetEvent), tuttavia Monitor è più veloce e non utilizza un nativo risorsa di sistema. Apparentemente anche Monitor è implementato in modalità utente ed è gestito, mentre Manual / AutoResetEvents richiede il passaggio alla modalità kernel e p / invocazione a chiamate native win32 che usano un handle di attesa.

Esistono situazioni in cui è necessario utilizzare Manual / AutoResetEvent, ad esempio, per segnalare tra processi che è possibile utilizzare eventi denominati e immagino che segnali thread nativi nella tua app.

Sto solo rigurgitando ciò che ho letto in questo eccellente articolo sulla discussione.

Vale la pena leggere l'intero articolo, tuttavia il collegamento conduce alla sezione handle di attesa che descrive in dettaglio gli eventi e monitora wait / pulse.

Dovresti usare un WaitHandle quando vuoi che un thread invii o riceva un segnale binario senza la necessità di una sezione critica. Monitor.Wait e Monitor.Pulse invece richiedono una sezione critica. Come la maggior parte dei meccanismi di sincronizzazione nel BCL, ci sono alcune sovrapposizioni nel modo in cui i due che hai citato possono essere usati. Ma, per un momento, non pensare di soddisfare lo stesso scopo.

Monitor.Wait e Monitor.Pulse sono un meccanismo di sincronizzazione molto più primitivo di un MRE o ARE. In effetti, puoi effettivamente costruire un MRE o ARE utilizzando nient'altro che la classe Monitor . Il concetto più importante da capire è la differenza tra i metodi Monitor.Wait e WaitHandle.WaitOne . Wait e WaitOne mettono entrambi il thread nello stato WaitSleepJoin , il che significa che il thread diventa inattivo e risponde solo a un thread . Interrompere o la rispettiva chiamata Pulse o Set . Ma, e questa è una grande differenza, Wait lascerà una sezione critica e la riacquisterà in modo atomico . WaitOne semplicemente non può farlo. È una differenza così fondamentale nel modo in cui questi meccanismi di sincronizzazione si comportano che definisce gli scenari in cui possono essere utilizzati.

Nella maggior parte dei casi sceglieresti MRE o ARE. Questi soddisfano la maggior parte delle situazioni in cui un thread deve ricevere un segnale da un altro. Tuttavia, se si desidera creare il proprio meccanismo di segnalazione, è necessario utilizzare Wait e Pulse . Ma, di nuovo, .NET BCL ha già coperto la maggior parte dei popolari meccanismi di segnalazione. I seguenti meccanismi di segnalazione esistono già 1 .

  • ManualResetEvent (o ManualResetEventSlim)
  • AutoResetEvent
  • Semaphore (o SemaphoreSlim)
  • EventWaitHandle
  • CountdownEvent
  • Barriera

1 Una menzione d'onore va alla classe BlockingCollection . Non è un meccanismo di segnalazione di per sé, ma ha le qualità di un meccanismo di segnalazione con l'ulteriore vantaggio di poter collegare i dati al segnale. In questo caso il segnale indica che un articolo è disponibile nella raccolta e i dati associati a quel segnale sono l'articolo stesso.

Questo tutorial ha descrizioni dettagliate di ciò che devi sapere: http://www.albahari.com/threading/

In particolare, questo riguarderà le classi XXXResetEvent,
http://www.albahari.com/threading/part2.aspx

e questo coprirà Wait / Pulse: http://www.albahari.com/threading/part4.aspx#_Wait_and_Pulse

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top