c# UI事件取消订阅-必需

本文关键字:必需 取消 UI 事件 | 更新日期: 2023-09-27 18:01:18

我知道取消订阅是必要的。我的问题来自生成的代码:当你从VS编辑器中修改ui,并向ui元素添加事件处理程序时(例如:private void BtnSampleClick(object sender, EventArgs e))

当创建此事件处理时,VS将此代码添加到private void InitializeComponent()自动生成代码

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

问题是VS没有在窗体的Dispose方法中自动添加取消订阅(this.btnSample.Click -= new System.EventHandler(this.BtnSampleClick);)。

通常我们应该把它们加在这里,对吧?如果不这样会泄漏到内存泄漏吗?我想检查一下是否有什么原因导致VS不自动取消订阅。也许表格是正确处理的,即使我们不这样做?

谢谢你在这件事上帮助我。

c# UI事件取消订阅-必需

没有这样做,主要是因为在本例中确实不需要。原因是您的窗体正在订阅具有由窗体管理的生命周期的对象的事件。从GC的角度来看,当对象(即按钮)被取消根时,表单也将被取消根(并关闭),因此没有内存泄漏的机会。. net中的GC是智能的——像这样的循环引用不是问题。

取消订阅事件仍然是一个很好的常规做法。如果您订阅对象上的事件,该事件的生存期独立于进行订阅的对象,则这一点非常重要。如果具有事件的对象比订阅者的寿命长得多,则尤其如此。在这种情况下,往往会发生事件引起的内存泄漏。例如,如果您的表单订阅了静态实例上的一个事件,并且忘记取消订阅,那么表单将永远不会被垃圾收集,因为委托引用将通过事件订阅使其"扎根"。

是的,明确退订是一种很好的做法。尽管它们可能导致内存泄漏,但只要它们不包含任何对非托管对象的引用,GC仍然可以在托管世界中正确地确定和清理。

你不需要关心这个。点。. NET框架有一个垃圾收集器(GC),它使用自己的原则自动处理(可能是在没有对对象的引用时)。

这并不意味着你永远不需要调用Dispose函数,在某些情况下,你故意调用Dispose()方法,以便内存不会耗尽,或者当我们使用本机dll/Marshal类