2011-02-26 7 views
5

¿Es esta una manera válida de usar un Lambda como un Manejador de eventos? Me parece que el controlador se ha eliminado correctamente y que el recolector de basura debería limpiarlo. Sin embargo, no he visto a nadie más hacerlo de esta manera, así que pensé que sería mejor que lo comprobara.¿Obtendrá esto basura recolectada?

En la misma línea, ¿cuál es la mejor herramienta (preferiblemente gratuita) para utilizar para comprobar si esto es, de hecho, basura recogida?

DispatcherTimer timer = new DispatcherTimer(); 
timer.Interval = TimeSpan.FromSeconds(10); 

EventHandler callback = null; 
callback = (s, e) => 
    { 
     timer.Stop(); 
     timer.Tick -= callback; 
    }; 

timer.Tick += callback; 
timer.Start(); 
+0

Para cualquier persona interesada, creé una prueba que ejecutó el código anterior 1M veces. El uso de la memoria se mantuvo incluso en todo momento. – herbrandson

Respuesta

3

Sí, la devolución de llamada será elegible para la recolección de basura después de que la devolución de llamada se haya ejecutado una vez. Esta es una forma razonable de suscribirse a un evento para ejecutar el controlador solo una vez.

Es difícil demostrar que el delegado será el recolector de basura - o de hecho que el objeto se utiliza para mantener las variables capturadas callback y timer será recogido de basura, es cierto ... usted realmente quiere poner un finalizador allí (que afecta a la recolección de basura en sí, por supuesto), pero no se puede, ya que es código generado.

4

Un DispatcherTimer se mantiene activo por la clase Dispatcher, mantiene un List<DispatcherTimer> internamente que almacena una referencia a cualquier temporizador que esté habilitado. Tan pronto como Detenga() el temporizador, el objeto se elimina de esa lista, por lo que es elegible para la recolección de basura si no almacena ninguna referencia adicional a la misma. Lo que no hace en este caso, la referencia del temporizador es una variable local.

No se puede obtener un finalizador en la clase generada automáticamente que implementa la lambda. Lo mejor es simplemente ejecutar este código mil millones de veces. Si no obtiene el consumo de miembro fugitivo y la OOM, obviamente no tiene fugas. Querrá acortar el intervalo para que no se prolongue hasta Navidad, 15 mseg es bueno. Use un temporizador para llamar al método, de modo que no obtenga demasiados temporizadores activos al mismo tiempo y permita que el despachador haga su trabajo.

Cuestiones relacionadas