考虑以下代码:

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:这当然不是一个真正的程序,我只是想向某人证明一点……但我的证明没有用;)

最佳答案

好的,我想我知道这是怎么回事...我用Reflector查看了Timer类的代码,并且在Enabled属性的 setter 中找到了以下指令:

this.timerRoot = GCHandle.Alloc(this);

因此,启动计时器后,计时器会为其分配一个GCHandle,以防止GC对其进行收集...

08-16 14:12