2011-11-21 41 views
5

Supongo que C# evenhandler tiene una lista de oyentes y recorre la lista al enviar un mensaje. Mi pregunta es cómo funciona esto internamente. ¿Hace una copia de la lista antes de pasarla y, de ser así, qué sucede si alguien se anula el registro después de que se haya copiado la lista pero todavía no ha recibido el mensaje?¿Cómo funciona C# eventhandler internamente?

¿Recibirá el mensaje aunque lo haya cancelado?

Respuesta

6

Un delegado es inmutable, por lo que cuando invoca a un delegado, la lista de suscriptores es conocida y corregida. Suscribirse o darse de baja reemplaza el delegado que respalda el evento.

Esto significa de hecho que en un escenario multi-hilo que puede recibir un evento después darse de baja, ya sea porque:

  1. el delegado ya estaba en proceso de ser invocado
  2. una instantánea de el delegado ya había sido obtenido para el propósito de invocar

por 2, me refiero a la pauta habitual (para evitar una Duri nula-ref invoke ng):

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) 

Por esa razón, si usted está codificando código multihilo complejo con eventos, se debe codificar la defensiva de tal manera que el evento de disparo después de cree que tiene suscritas no es un problema.

Estos matices realmente no afectan el código de un solo subproceso.

Cuestiones relacionadas