Tome la siguiente clase de C #:
c1 {
event EventHandler someEvent;
}
Si hay una gran cantidad de suscripciones a c1
's someEvent
evento y quiero aclarar a todos, ¿cuál es la mejor manera de lograr esto? También tenga en cuenta que las suscripciones a este evento podrían ser / son lambdas / delegados anónimos.
Actualmente mi solución es agregar un ResetSubscriptions()
método a c1
ese conjunto someEvent
como nulo. No sé si esto tiene consecuencias invisibles.
EventHandlerList
, es posible que pueda hacerlo. Sin embargo, tendría que reconocer esos dos casos, y podría haber muchas otras implementaciones.hidden
.Agregue un método a c1 que establecerá 'someEvent' en nulo.
fuente
Es mejor usar
delegate { }
quenull
evitar la excepción de referencia nula.fuente
List.Clear()
vsmyList = null
.Establecer el evento como nulo dentro de la clase funciona. Cuando desecha una clase, siempre debe establecer el evento como nulo, el GC tiene problemas con los eventos y puede no limpiar la clase eliminada si tiene eventos colgantes.
fuente
La mejor práctica para borrar todos los suscriptores es establecer someEvent en nulo agregando otro método público si desea exponer esta funcionalidad al exterior. Esto no tiene consecuencias invisibles. La condición previa es recordar declarar SomeEvent con la palabra clave 'event'.
Consulte el libro - C # 4.0 en pocas palabras, página 125.
Alguien aquí propuso usar el
Delegate.RemoveAll
método. Si lo usa, el código de muestra podría seguir el siguiente formulario. Pero es realmente estúpido. ¿Por qué no soloSomeEvent=null
dentro de laClearSubscribers()
función?fuente
Puede lograr esto utilizando los métodos Delegate.Remove o Delegate.RemoveAll.
fuente
Comentario aburrido extendido conceptual.
Prefiero usar la palabra "controlador de eventos" en lugar de "evento" o "delegado". Y usé la palabra "evento" para otras cosas. En algunos lenguajes de programación (VB.NET, Object Pascal, Objective-C), "evento" se denomina "mensaje" o "señal", e incluso tiene una palabra clave "mensaje" y una sintaxis específica de azúcar.
Y, para responder a ese "mensaje", un "controlador de eventos" responde, ya sea un delegado único o múltiples delegados.
Resumen: "Evento" es la "pregunta", "controlador de eventos" son las respuestas.
fuente
Esta es mi solución:
Debe llamar
Dispose()
o usar unusing(new Foo()){/*...*/}
patrón para cancelar la suscripción de todos los miembros de la lista de invocación.fuente
Elimine todos los eventos, suponga que el evento es del tipo "Acción":
fuente
GetInvocationList
.En lugar de agregar y eliminar devoluciones de llamada manualmente y tener un montón de tipos de delegado declarados en todas partes:
Podrías probar este enfoque genérico:
fuente