我知道必须从事件中取消订阅。
我的问题来自生成的代码:
从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是否有自动执行取消订阅的原因。即使我们不这样做,表格也可以正确处理?
感谢您帮助我在这件事上轻描淡写!
答案 0 :(得分:6)
这没有完成,主要是因为在这种情况下实际上没有必要。原因是您的表单订阅了由表单管理的生命周期的对象事件。当对象(即:按钮)从GC透视图中退出时,表单也将被无根(并且关闭),因此不存在内存泄漏的可能性。 .NET中的GC很聪明 - 像这样的循环引用不是问题。
然而,取消订阅活动仍然是一个很好的通用做法。如果您在一个对象上订阅一个事件变得很重要,该对象的生命周期与正在进行订阅的对象无关。如果具有事件的对象比订阅者长得多,则尤其如此。这种情况是事件引起的内存泄漏倾向于发生的地方。例如,如果您的表单订阅静态实例上的事件,并忘记取消订阅,则表单永远不会被垃圾收集,因为委托引用将通过事件订阅使其“生根”。
答案 1 :(得分:1)
是的,明确取消订阅是一个好习惯。虽然它们可能导致内存泄漏,但只要它们没有对非托管对象进行任何引用,GC仍然可以在托管环境中正确地确定和清理。
答案 2 :(得分:0)
你无需关心这一点。 Dot.NET框架有一个垃圾收集器(GC),它使用自己的原理自动处理(可能是在没有对象的引用时)。
这并不意味着您永远不需要调用Dispose函数,在某些情况下,您有意调用Dispose()方法以便内存不会耗尽,或者当我们使用本机dll / Marshal类时