我必须取消订阅所有活动处理程序吗?

时间:2009-08-27 14:44:41

标签: c# .net winforms

在VS中的Designer中,假设您双击按钮并生成此Click事件处理程序。

订阅代码在designer.cs中。

我想知道,在处理中,表格必须取消订阅活动吗?

此外,表格中的所有控件是否会在表格处理时处理?它实际上是递归调用每个控件上的dispose吗?

3 个答案:

答案 0 :(得分:15)

如果要挂钩自己的活动,则无需在Dispose上取消挂钩事件。

如果要在另一个对象中挂钩事件,则只需要担心它。这样做的原因是事件挂钩将引用保持为订阅者。如果你没有解开,只要观察者还活着,你就不会收集垃圾。

当你挂钩自己的活动时,你有自己的参考,这是循环的,所以你不必担心它。

由于这个原因,我来支持更松散耦合的事件模式。这是.Net内存泄漏的第一名。我更喜欢Event Aggregator模式(使用weak events)。

答案 1 :(得分:2)

关于“它是否实际上会递归地调用每个控件上的处理?”的问题,答案是肯定的。

可以通过在控件的Dispose方法中放置一个断点来完成一个简单的测试。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        this.Controls.Add(new SuperButton());
    }
}

public class SuperButton : Button
{
    protected override void Dispose(bool disposing)
    {
        //Place breakpoint on the line below
        base.Dispose(disposing); 
    }
}

答案 2 :(得分:1)

只要事件处理程序代码是表单本身,那么您就不需要取消订阅事件 - 因为控件没有悬空事件处理程序,因为表单本身会被破坏