【问题标题】:Must I unsubscribe all event handlers?我必须取消订阅所有事件处理程序吗?
【发布时间】:2009-08-27 14:44:40
【问题描述】:

在 VS 的设计器中,假设您双击一个按钮,它会生成这个 Click 事件处理程序。

订阅代码在designer.cs 中。

我想知道,在处置表单时,我必须取消订阅该活动吗?

另外,表单中的所有控件都会在表单释放时被释放吗?它实际上是递归调用每个控件的 dispose 吗?

【问题讨论】:

    标签: c# .net winforms


    【解决方案1】:

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

    如果您将事件挂钩到另一个对象中,您只需要担心它。这样做的原因是事件挂钩使订阅者的引用保持活动状态。如果你没有解开钩子,那么只要 observable 还活着,你就不会收集垃圾。

    当你挂钩自己的事件时,你有一个对自己的引用,这是循环的,因此你不必担心它。

    出于这个原因,我开始支持更松散耦合的事件模式。这是 .Net 中内存泄漏的第一名。我更喜欢Event Aggregator 模式(带有weak events)。

    【讨论】:

    • 感谢您的精彩解释。当你自己上钩时不要解开钩子是非常有意义的。
    【解决方案2】:

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

    可以通过在控件的 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); 
        }
    }
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-08
        • 2012-06-15
        • 2021-03-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多