2011-11-21 14 views
5

Immagino che C# evenhandler abbia una lista di ascoltatori e giri attraverso la lista quando invia un messaggio. La mia domanda è come funziona internamente. Fa una copia dell'elenco prima di eseguirne il ciclo e, in tal caso, cosa accade se qualcuno si annulla automaticamente dopo che l'elenco è stato copiato ma non ha ancora ricevuto il messaggio.Come funziona l'eventmanler C# internamente?

Continuerà a ricevere il messaggio anche se si è annullato la registrazione?

risposta

6

Un delegato è immutabile, quindi quando si richiama un delegato, l'elenco degli abbonati è noto e corretto. La sottoscrizione o annullamento dell'iscrizione di sostituisce il delegato che è alla base dell'evento.

Questo in effetti significa che in uno scenario multi-threaded è possibile ricevere un evento dopo annullamento dell'iscrizione, perché o:

  1. il delegato era già in procinto di essere invocato
  2. un'istantanea di il delegato era già stata ottenuta per la scopo di invocare

da 2, intendo lo schema usuale (per evitare un duri null-ref ng invoke):

var handler = SomeEvent; 
// <===== another thread could unsubscribe at this point 
if(handler != null) handler(sender, args); // <== or part way through this invoke 
// (and it either case, have the event trigger even though they think they have 
// unsubscribed) 

Per questo motivo, se si esegue la codifica del codice complesso multi-threaded con eventi, si dovrebbe codificare difensiva in modo tale che l'evento sparando dopo pensi di avere annullato l'iscrizione non è un problema.

Queste sfumature non hanno alcun impatto sul codice a thread singolo.

Problemi correlati