Таймер, события и сбор мусора: я что-то упускаю?

Рассмотрим следующий код:

class TestTimerGC : Form
{
    public TestTimerGC()
    {
        Button btnGC = new Button();
        btnGC.Text = "GC";
        btnGC.Click += (sender, e) => GC.Collect();
        this.Controls.Add(btnGC);

        System.Windows.Forms.Timer tmr = new System.Windows.Forms.Timer();
        tmr.Interval = 1000;
        tmr.Tick += (sender, e) => this.Text = DateTime.Now.ToString();
        tmr.Start();
    }
}

Если я не ошибаюсь, после того, как переменная tmr выходит за пределы области видимости, Timer не ссылается нигде, поэтому она должна иметь право на сбор мусора. Но когда я нажимаю кнопку GC, таймер продолжает работать, поэтому я думаю, что он не был собран...

Есть ли у кого есть объяснение?

PS: это не настоящая программа, конечно, я просто пытался доказать кому-то точку... но мое доказательство не срабатывало;)

Ответы

Ответ 1

ОК, я думаю, что знаю, что происходит... Я просмотрел код класса Timer с Reflector, и я нашел следующую инструкцию в настройщике свойства Enabled:

this.timerRoot = GCHandle.Alloc(this);

Итак, когда он запускается, таймер выделяет GCHandle для себя, что предотвращает его сбор с помощью GC...