考虑以下代码:
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对其进行收集...