c# - 计时器、事件和垃圾收集 : am I missing something?

标签 c# .net garbage-collection timer

考虑以下代码:

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

最佳答案

OK,我想我知道发生了什么......我用Reflector查看了Timer类的代码,在Enabled<的setter中发现了如下指令属性:

this.timerRoot = GCHandle.Alloc(this);

因此,当它启动时,定时器会为自己分配一个GCHandle,这会阻止它被 GC 收集...

关于c# - 计时器、事件和垃圾收集 : am I missing something?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2311027/

相关文章:

.net - 使用异步 Socket.BeginReceive 时如何检测超时?

python - 内存增长虽然被覆盖

c# - 为 Mac (C#/Mono) 创建一个没有停靠图标的应用程序

c# - 具有折叠/展开功能的控件 TreeView

c# - 通过 HTTP 向客户端发送字节数组时操作缓慢且无响应主体

.net - 从 .NET GC 的角度来看,在非托管代码中导致过早收集的事件顺序是什么?

python - 在 Python 中回收大对象的内存 - Windows 和 Ubuntu 的区别

c# - SetSysTrayVisible 错误 Windows Phone 8

c#处理空格键事件

c# - C# 中的递归正则表达式