2011-08-31 21 views
5

En el siguiente código, creo un DispatcherTimer en el constructor de la clase. Nadie guarda referencia en eso.Recolección de basura del objeto C# declarado en el constructor

En mi entender, el recolector de basura debe recuperar el temporizador poco tiempo después de abandonar el alcance del constructor. ¡Pero eso no sucede! Incluso después de forzar una recolección de basura con GC.Collect()

¿Qué está pasando debajo del capó?

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     new DispatcherTimer 
     { 
      Interval = TimeSpan.FromMilliseconds(100), 
      IsEnabled = true 
     } 
     .Tick += (s, e) => 
     { 
      textBlock1.Text = DateTime.Now.ToString(); 
     }; 
    } 
} 

Respuesta

3

Cuando acaba de construir el a DispatcherTimer, nada impide que sea GCed. Sin embargo, configura IsEnabled = true, que llamará al Start() en el temporizador. Cuando eso, sucede, esta línea de código se ejecutará:

this._dispatcher.AddTimer(this); 

Y ahora el Dispatcher sí está arraigando el temporizador, lo que significa que no puede ser GCed.

4

temporizadores son bastante especial ya que se arraigan llamando

this.timerRoot = GCHandle.Alloc(this); 

algunos enlaces

EDIT:

No nos dimos cuenta de que era un DispatcherTimer - que no sino afianzarse directamente, sino indirectamente (a la Dispatcher) que a su vez conduce al mismo efecto ...

+0

Esto está realmente mal ... es un tipo diferente de temporizador. – dlev

+0

¿Están DispatcherTimers sujetos a las mismas reglas de recolección de basura que Threading.Timers? Si es así, no tener una referencia de campo (solo una referencia local) para el temporizador causaría la recolección de basura en sí misma ... pero no creo que ese sea el caso con DispatcherTimers ... – Jeff

+0

@ JeffN825 Todos los objetos están sujetos a las mismas reglas de GC: si eres inalcanzable desde una raíz de GC, entonces eres elegible para GC. En este caso, ese código no es ni siquiera * desde * la clase de temporizador correcta. – dlev

1

Se agregará a la cola Dispatcher que será rooteada.

Cuestiones relacionadas