Nota: He editado esta pregunta para que sea más fácil para otras personas con el mismo problema obtener ayuda aquí. Para ver la pregunta original que se ajusta mejor con algunas de las respuestas, consulte el historial de edición.Problema con el "encadenamiento" de eventos
En un proyecto tengo una clase ExecutionManager que puede contener varias instancias de ExecutionSlot. La clase ExecutionSlot tiene varios campos de eventos públicos como este:
public event EventHandlers.ObjectEventHandler<IPlugin> ExecuteCompleted;
Para cada uno de estos eventos hay un evento correspondiente en ExecutionManager. El comportamiento deseado es que cada vez que se lanza un evento en ExecutionSlot, el evento coincidente también se genera en el ExecutionManager que lo contiene.
La solución implmented era que cada vez que se añadió un ExecutionSlot a un ExecutionManager la ExectionManager sería añadir sus propios eventos a los de ExecutionSlot así:
executionSlot.ExecuteCompleted += ExecuteCompleted;
No hay necesidad todavía de eliminar un ExecutionSlot, por lo que los eventos nunca se eliminan tampoco.
El problema es que el evento en ExecutionManager no se está iniciando. Después de confirmar que un evento estaba siendo reaised por un ExecutionSlot descubrí que la modificación de la línea anterior a la siguiente solucionado el problema:
executionSlot.ExecuteCompleted += (sender, eventArgs) => ExecuteCompleted(sender, eventArgs);
Y yo no podía entender por qué, así que mi pregunta era, ¿cuál era la diferencia .
El motivo de esta diferencia es que el primero agrega los oyentes actuales del evento ExecutionManager al evento ExecutionSlot. Por lo tanto, los oyentes que se agreguen más adelante no se invocarán cuando se genere el evento. En contraste, la última solución usa una lambda para elevar el evento del ExecutionManager, lo que significa que se llamará a los oyentes en el momento del evento.
El motivo subyacente de la falla de la primera solución es que los delegados son inmutables. Entonces, cuando agrega un nuevo delegado y un evento, en realidad está creando un nuevo delegado que contiene los delegados existentes y el agregado. Por lo tanto, cualquier referencia a los delegados realizada anteriormente no contendrá el delegado recién agregado.
tal vez invierta sus ediciones a su pregunta original, luego haga otra pregunta y respóndala, con referencias de ida y vuelta. – JoelFan
Veo el punto de mantener el texto original ya que para eso son las respuestas. Pero dado que el texto original no era lo suficientemente claro, creo que el nuevo texto será una mejor ayuda para los demás, en comparación con las preguntas casi duplicadas. –