2008-10-09 10 views
28

¿Es una buena práctica para implementar la gestión de eventos a través WeakReference si ese evento es el único que mantiene la referencia y que necesitaría el objeto que se recoge la basura?WeakReference y manejo de eventos

como argumento para esto:

La gente dice que si se suscribe a algo que es su responsabilidad para darse de baja y que debe hacerlo.

+0

La pregunta es: ¿Cuáles son las posibilidades de que ese evento se dispare cuando se recoge el objeto? ¿Por qué usar una WeakReference en primer lugar? –

+0

@Jon Limjap sin una referencia débil, ¿no es esa posibilidad cero porque el evento mantiene una pista del objeto y, por lo tanto, no se recogerá? – fostandy

+0

@fostandy: No, el suscriptor no mantendrá vivo al editor de un evento, solo funciona al revés. Para permitir que los suscriptores reciban el GC sin tener que darse de baja primero, uno debe usar WeakReference. Ver: http://stackoverflow.com/a/298276/134761 – angularsen

Respuesta

-2

Si bien lo que usted sugiere resuelve una serie de problemas de gestión de referencia (evento y de prevención de pérdida de memoria), es probable que se abra un nuevo conjunto de problemas.

Un problema que puedo ver es durante el proceso de manejo de eventos si el objeto fuente es basura (ya que solo se mantuvo con una referencia débil), cualquier código que acceda al objeto fuente dará como resultado una excepción de referencia nula. Puede argumentar que el controlador de eventos no debe acceder al objeto fuente o debe tener una referencia fuerte, pero se puede argumentar que este podría ser un problema peor que el que está tratando de resolver en primer lugar.

+1

Cuando CLR ya ejecuta el controlador de eventos, la pila mantendrá la referencia a "this" y los objetos no serán recopilados. –

9

El patrón de delegado débil es algo que debería estar presente en CLR. Los eventos normales exhiben semántica de "notifícame mientras estás vivo", mientras que a menudo necesitamos "notificarme mientras estoy vivo". Simplemente tener delegado en WeakReference es incorrecto, porque el delegado también es un objeto e incluso cuando el destinatario aún está vivo y tiene referencias entrantes, el delegado mismo solo está siendo referenciado por dicha WeakReference y se recopilará instantáneamente. Ver this old post para un ejemplo de implementación.

6

Referencias débiles en sí mismas, no resuelven el problema ya que el delegado posee la referencia. En la Biblioteca de aplicaciones compuestas que se envía con Prism (www.microsoft.com/compositewpf) hay una clase WeakDelegate que puede extraer de la fuente. El WeakDelegate básicamente refleja y crea un delegado solo por un momento en el tiempo y luego lo libera, por lo tanto, no contiene ningún puntero. Dentro de CAL es utilizado por la clase EventAggregator, pero usted es libre de extraerlo para su propio uso, ya que está bajo MS-PL.

13

Es bueno tener el hábito de darse de baja de eventos cuando se puede, pero a veces no hay un método obvio de "limpieza" en la que se puede hacer. Recientemente publicamos un blog article sobre este tema; Incluye métodos que hacen que sea fácil suscribirse a un evento con WeakReference.