Es necesario comprender lo que está haciendo System.Timers.Timer
detrás de las escenas. Es un contenedor alrededor de la clase System.Threading.Timer
. Cuando se inicia el temporizador crea una nueva instancia de System.Threading.Timer
y le pasa un método de devolución de llamada en la instancia System.Timers.Timer
. El sistema hace referencia a este delegado de devolución de llamada siempre que el temporizador permanezca habilitado.
También sabemos que los delegados mantienen una referencia a una instancia de la clase que contiene el método de destino. Esta es la razón por la que su instancia System.Timers.Timer
no se recopila y no se detiene automáticamente. La eliminación del controlador de eventos Elapsed
no resolverá este problema porque ese delegado solo contiene una referencia a la instancia TrayForm
. Nuevamente, es el System.Threading.Timer
el que mantiene una referencia al System.Timers.Timer
. Toda la cadena de referencia permanece enraizada porque el sistema tiene que hacer referencia al System.Threading.Timer
para que funcione.
Aquí es la cadena de referencia:
System => _TimerCallback => Callback => System.Threading.Timer => Callback => System.Timers.Timer
Cuando realiza un seguimiento de esto con reflector o ILSpy se puede ver que el "sistema" en la cadena de referencia anterior entra en juego a través del método TimerBase.AddTimerNative
que está marcado MethodImplOptions.InternalCall
por lo que no podemos ver exactamente cómo la raíz de la referencia está debajo de este punto. Pero, está arraigado de todos modos.
Si desactiva el temporizador a través de Enabled = false
o Stop
entonces será disponer el System.Threading.Timer
subyacente, que a su vez debería dejar de hacer referencia a la System.Timers.Timer
.
Evene si se pudo recopilar la referencia, que no puede, ** tiene la llamada para recopilar antes de que la variable salga del alcance. ** El recolector no va a recopilar algo que todavía está en el alcance. (El jitter está * permitido * para darse cuenta de que la última referencia a la variable está antes de la llamada para recopilar y permitir que se recopile, pero * en general * su técnica aquí no tiene sentido; no debe confiar en el jitter ¡diciéndole al recaudador que recoja cosas que todavía están en el alcance! –
Es cierto - ¡gracias! – Niklas
Esta pregunta se ha hecho muchas veces, vea la sección "relacionada" a la derecha. La respuesta corta es: los temporizadores son especiales; se mantienen vivos. De lo contrario, serían bastante inútiles, se presume que hizo un temporizador porque quiere que siga funcionando. –