2011-07-07 84 views
4

我知道必须从事件IS取消订阅。 我的问题来自于生成的代码: 当您修改从VS编辑器的用户界面,并添加事件处理程序的UI元素(例如: private void BtnSampleClick(object sender, EventArgs e)C#UI事件取消订阅 - 必要?

在创建这个事件处理,VS添加此代码该自动生成的private void InitializeComponent()代码

this.btnSample.Click += new System.EventHandler(this.BtnSampleClick); 

问题是,VS不会在形式的Dispose方法自动添加退订(this.btnSample.Click -= new System.EventHandler(this.BtnSampleClick);)。

通常我们应该在那里添加它们吗?如果没有,这将泄漏到内存泄漏? 想检查是否有VS不会自动执行取消订阅的原因。即使我们不这样做,也许表格是正确处理的?

感谢您帮助我在这件事情上削减一些光!

回答

6

这没有完成,主要是因为在这种情况下真的不是必需的。原因是您的表单正在订阅由表单管理的对象的事件。从GC的角度来看,当对象(即:按钮)被解除连接时,表单也将被解除连接(并关闭),所以不会有内存泄漏的机会。 .NET中的GC很聪明 - 像这样的循环引用不是问题。

但是,取消订阅活动仍然是一个很好的通用实践。如果您在具有与正在进行订购的对象无关的生命周期的对象上订阅事件,则变得非常重要。如果具有事件的对象比用户长得多,这尤其如此。这种情况往往会发生事件引起的内存泄漏。例如,如果您的Form订阅了一个静态实例上的事件,并且忘记取消订阅,则表单将永远不会被垃圾收集,因为委托引用将通过事件订阅使它“保持根源”。

+0

+1解释这是因为同步生命周期。 – Ergwun

1

是的,这是一个很好的做法,明确退订。尽管它们可能导致内存泄漏,但只要它们没有引用非托管对象,GC仍然可以在托管的环境中正确地确定和清除。

0

你不需要关心那件事。 Dot.NET框架有一个垃圾收集器(GC),它可以使用自己的原理自动处理(可能是当没有引用剩下的对象时)。

这并不意味着你永远不需要调用Dispose功能,在某些情况下,你刻意调用Dispose()方法,以使内存没有用完,或当我们与本地的dll/Marshal类工作