Таймер, событие и сборка мусора: я что-то упустил? - PullRequest
15 голосов
/ 22 февраля 2010

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

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 Ответ

21 голосов
/ 22 февраля 2010

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

this.timerRoot = GCHandle.Alloc(this);

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

...