ejemplo - eventos c#
Cómo elimino el registro del controlador de evento ''anónimo'' (7)
¿Necesita anular el registro por un motivo distinto a la fuga?
Con respecto al bit "O simplemente permita que la memoria se filtre", cuando el Recolector de basura limpia el Sujeto, su delegado anónimo debe limpiarse también, por lo que no debe haber una fuga.
Esta pregunta ya tiene una respuesta aquí:
- Darse de baja método anónimo en C # 11 respuestas
Di si escucho un evento:
Subject.NewEvent += delegate(object sender, NewEventArgs e)
{
//some code
});
¿Ahora cómo puedo anular el registro de este evento? ¿O simplemente permite que la memoria se filtre?
Asigne un nombre a su instancia del delegado anónimo:
EventHandler<NewEventArg> handler = delegate(object sender, NewEventArgs e)
{
//some code
};
Subject.NewEvent += handler;
Subject.NewEvent -= handler;
Hay otra pregunta (la mía) que entra en esto en algunos (demasiado) detalle: Modelo de manejador de eventos débil para usar con lambdas .
Sin embargo, ahora que ha surgido el Framework Reactive , seriamente consideraría investigar eso en este tipo de situaciones.
Necesita un nombre para su función anónima, y luego, solo puede hacerlo mientras el nombre esté dentro del alcance:
var handler = new EventHandler(delegate(object o, EventArgs e)
{
//do something...
};
Subject.NewEvent += handler;
// later on while handler is still in scope...
Subject.NewEvent -= handler;
Para eliminar el controlador en la primera invocación:
//SubjectType Subject = ..... already defined if using (2)
EventHandler handler = null;
handler = delegate(object sender, EventArgs e)
{
// (1)
(sender as SubjectType).NewEvent -= handler;
// or
// (2) Subject.NewEvent -= handler;
// do stuff here
};
Subject.NewEvent += handler;
Puede crear un método para anular el registro de todos los oyentes del evento. Esto no es exactamente lo que quieres, pero a veces puede ser útil. Por ejemplo (esto realmente funciona =)):
class Program {
static void Main(string[] args) {
A someClass = new A();
someClass.SomeEvent += delegate(object sender, EventArgs e) {
throw new NotImplementedException();
};
someClass.ClearEventHandlers();
someClass.FireEvent();
Console.WriteLine("No error.");
}
public class A {
public event EventHandler SomeEvent;
public void ClearEventHandlers() {
Delegate[] delegates = SomeEvent.GetInvocationList();
foreach (Delegate delegate in delegates) {
SomeEvent -= (EventHandler) delegate;
}
}
public void FireEvent() {
if (SomeEvent != null) {
SomeEvent(null, null);
}
}
}
}
Si necesita cancelar el registro de un evento, le recomiendo evitar delegados anónimos para el controlador de eventos.
Este es un caso en el que asignarlo a un método local es mejor: puede darse de baja del evento limpiamente.