¿Hay alguna manera de saber si se ha agregado un controlador de eventos a un objeto? Estoy serializando una lista de objetos dentro / fuera del estado de sesión para que podamos usar el estado de sesión basado en SQL ... Cuando un objeto en la lista tiene una propiedad modificada, debe marcarse, lo que el controlador de eventos se ocupó correctamente antes . Sin embargo, ahora cuando los objetos están deserializados, no está obteniendo el controlador de eventos.
En un ataque de molestia leve, acabo de agregar el controlador de eventos a la propiedad Get que accede al objeto. Se llama ahora, lo cual es genial, excepto que se llama como 5 veces, así que creo que el controlador se sigue agregando cada vez que se accede al objeto.
Es realmente lo suficientemente seguro como para ignorarlo, pero prefiero hacerlo mucho más limpio verificando si el controlador ya se ha agregado, por lo que solo lo hago una vez.
¿Es eso posible?
EDITAR: No necesariamente tengo el control total de qué controladores de eventos se agregan, por lo que solo verificar nulo no es lo suficientemente bueno.
Respuestas:
Desde fuera de la clase definitoria, como menciona @Telos, solo puede usar EventHandler en el lado izquierdo de a
+=
o a-=
. Por lo tanto, si tiene la capacidad de modificar la clase definitoria, puede proporcionar un método para realizar la verificación al verificar si el controlador de eventos esnull
; de ser así, no se ha agregado ningún controlador de eventos. Si no, entonces tal vez y pueda recorrer los valores en Delegate.GetInvocationList . Si uno es igual al delegado que desea agregar como controlador de eventos, entonces sabe que está allí.Y esto podría modificarse fácilmente para convertirse en "agregar el controlador si no está allí". Si no tiene acceso a las entrañas de la clase que expone el evento, es posible que deba explorar
-=
y+=
, como lo sugiere @Lou Franco.Sin embargo, es mejor que vuelva a examinar la forma en que está encargando y desmantelando estos objetos, para ver si no puede encontrar una manera de rastrear esta información usted mismo.
fuente
Delegate.Equals(objA, objB)
si desea verificar exactamente la misma existencia de delegado. De lo contrario, compare las propiedades individualmenteif(objA.Method.Name == objB.Method.Name && objA.Target.GetType().FullName == objB.Target.GetType().FullName)
.Recientemente llegué a una situación similar en la que necesitaba registrar un controlador para un evento solo una vez. Descubrí que puede anular el registro de forma segura primero, y luego registrarse nuevamente, incluso si el controlador no está registrado en absoluto:
Tenga en cuenta que hacer esto cada vez que registre su controlador se asegurará de que su controlador se registre solo una vez. Suena como una muy buena práctica para mí :)
fuente
Si este es el único controlador, puede verificar si el evento es nulo; de lo contrario, se agregó el controlador.
Creo que puede llamar de forma segura - = en el evento con su controlador incluso si no se agrega (si no, puede atraparlo) - para asegurarse de que no esté allí antes de agregar.
fuente
Este ejemplo muestra cómo usar el método GetInvocationList () para recuperar delegados a todos los controladores que se han agregado. Si está buscando ver si se ha agregado un controlador específico (función), puede usar la matriz.
Puede examinar varias propiedades en la propiedad Método del delegado para ver si se ha agregado una función específica.
Si está buscando ver si solo hay uno conectado, puede probar nulo.
fuente
Si entiendo su problema correctamente, puede tener problemas más grandes. Dijiste que otros objetos pueden suscribirse a estos eventos. Cuando el objeto se serializa y deserializa, los otros objetos (los que no tiene control) perderán sus controladores de eventos.
Si no está preocupado por eso, mantener una referencia a su controlador de eventos debería ser lo suficientemente bueno. Si le preocupan los efectos secundarios de otros objetos que pierden sus controladores de eventos, entonces puede que desee repensar su estrategia de almacenamiento en caché.
fuente
Estoy de acuerdo con la respuesta de alf, pero poca modificación es, para usar,
fuente
La única forma en que funcionó para mí es creando una variable booleana que configuré como verdadera cuando agregué el evento. Luego pregunto: si la variable es falsa, agrego el evento.
Esta variable puede ser global.
fuente
fuente