2009-05-29 14 views
5

En una clase, Clase A, tengo un objeto de temporizador. En esta clase, registro los manejadores de eventos para el evento transcurrido del temporizador. En otra clase, ClassB, tengo un controlador de eventos público para el evento transcurrido del temporizador. Así que registrar el controlador de eventos de ClassB en claseA de la siguiente manera:¿Qué sucede cuando se desencadena un evento e intenta ejecutar un controlador de eventos en un objeto que ya no existe?

myTimer.Elapsed += ClassBInstance.TimerElapsed 

¿Qué ocurre si tuviera que crear una nueva instancia de ClassBInstance y ha transcurrido el tiempo activa el evento cuando la instancia anterior del controlador de eventos de ClassB sigue siendo vinculado al evento transcurrido del temporizador?

Por ejemplo:

ClassB classBInstance = new ClassB(); 
myTimer.Elapsed += classBInstance.TimerElapsed 

classBInstance = new ClassB(); 
myTimer.Elapsed += classBInstance.TimerElapsed 

Respuesta

10

yo sepa, no es ClassBInstance basura recogida, siempre y cuando hay eventos registrados, ya que el evento contiene una referencia a la misma.

Debe asegurarse de anular el registro de todos los eventos de instancias que ya no se utilizan.

Importante: son casos en los que la instancia registrada es IDisposable, porque el evento se puede disparar cuando se elimina la instancia. En este caso, me resultó más fácil dejar que la instancia se registre y anular el registro en Dispose.

+5

Indeed. En particular, esta es la razón por la cual los eventos estáticos son tan peligrosos; es muy fácil mantener una gran cantidad de objetos vivos si no se da de baja religiosamente. Al menos los eventos de instancia mueren con la instancia que contiene el campo de respaldo, pero no el GC para estadísticas. –

+0

También vale la pena mencionar que WPF salta a través de aros para evitar esto con WeakEvents que en mi humilde opinión son demasiado complicados y que necesitan un poco de soporte de idiomas. – Josh

2

Si la instancia anterior todavía está activa y la nueva instancia también ha conectado un controlador de eventos, el evento activará ambos controladores (uno a la vez). Es importante hacer un seguimiento de cuándo se adjuntan controladores de eventos a los eventos, que también los separe cuando ya no los necesiten. De lo contrario, las instancias anteriores seguirán viviendo en la memoria, ejecutando controladores de eventos que pueden generar resultados inesperados.

3

Los eventos se implementan de tal manera que, mientras su editor esté vivo, el editor mantendrá vivos a todos los suscriptores, incluso si no tiene otras referencias a estos.

Por supuesto, esto también implica que debe separar los suscriptores, si desea que se eliminen independientemente del editor.

0

Puedes usar mi WeakEventHandler, basado en WeakReference. Como mantiene una referencia débil al oyente del evento, no obliga al oyente a vivir.

see this answer

Cuestiones relacionadas