In the following code, I create a DispatcherTimer in the class's constructor. No one keeps reference on it.
In my understanding, the timer should be reclaimed by the garbage collector some time after leaving the constructor's scope.
But that doesn't happen! Even after forcing a garbage collection with GC.Collect()
What is going on under the hood?
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(100),
IsEnabled = true
}
.Tick += (s, e) =>
{
textBlock1.Text = DateTime.Now.ToString();
};
}
}
Timers are rather special since they root themselves by calling
this.timerRoot = GCHandle.Alloc(this);
some links
EDIT:
Didn't realize that it was a DispatcherTimer
- that doesn't root itself directly but indirectly (to the Dispatcher
) which in turn leads to the same effect...
When you just construct the a DispatcherTimer
, nothing prevents it from be GCed. However, you set IsEnabled = true
, which will call Start()
on the timer. When that, happens, this line of code will be executed:
this._dispatcher.AddTimer(this);
And now the Dispatcher
itself is rooting the timer, meaning it can't be GCed.
It will be added to the Dispatcher
queue which will be rooted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With