【问题标题】:Should I implement a Dispose for a User Control that has event handlers?我应该为具有事件处理程序的用户控件实现 Dispose 吗?
【发布时间】:2012-04-13 10:49:02
【问题描述】:

我有一个自定义控件 CustomContainer,其中包含另一系列自定义控件 (CustomButtons)。

所以控件CustomContainer有5个CustomButtons。

每个 CustomButtons 都有和 Click 事件处理程序,它连接在 CustomContainer 的构造函数中。

我是否需要为 Control CustomContainer 编写覆盖 Dispose(因为它从 UserControl 继承,所以有一个 Dispose)来取消连接这些 CustomButtons 事件处理程序?标准处理是否足够,或者我会在这里有内存泄漏?

谢谢, A.

【问题讨论】:

  • Mark 对这个问题有很好的回答。
  • @SwDevMan81 这个问题比我的好多了:)

标签: c# custom-controls dispose


【解决方案1】:

大多数涉及控制事件的情况下,可以在不处理事件的情况下放弃事件而不会遇到麻烦,因为事件发布者和订阅者通常会同时超出范围。在某些方面,这是不幸的,因为如果事件清理被认为是正确性所必需的,那么可能会有语言支持,任何写得体面的代码都会理所当然地清理事件。

问题在于,任何阻止被遗弃的事件发布者被垃圾收集的东西也会阻止它的任何订阅者被垃圾收集;如果这些订阅者发布了他们自己的任何事件,那么他们的所有订阅者也将不必要地免受垃圾收集等的影响。例如,假设一个人有一个运行良好的程序,但是一个人添加了一个事件来让表单知道当打开或关闭另一个表单时,每个表单都可以有一个“Windows”菜单列出其他打开的表单。不错的功能。但是,如果在未取消订阅提供此类通知的事件的情况下处置表单,则此类失败可能会阻止表单或其任何控件或这些事物所引用的任何其他对象被收集。严重的内存泄漏,尽管只有在程序的生命周期内打开和关闭多个文档时才可能导致问题,因此除非最终用户发现,否则可能无法发现。

我的建议是使用表单的Disposed 事件来处理事件清理。可以更改设计器生成的Dispose 代码,设计器可能会不理会这些更改,但鉴于存在Disposed 事件,我认为避免对设计器生成的文件进行任何修补会更干净。

【讨论】:

    【解决方案2】:

    不,您不需要实现IDisposable 和实现Dispose() 用于从您拥有的事件处理程序中取消订阅。您拥有的事件处理程序的存在(根据帖子,按钮单击)不会导致内存泄漏。

    【讨论】:

      【解决方案3】:

      IDisposable 用于清理非托管资源。所有托管资源都由垃圾收集器清理。当没有更多对该对象的引用时,下次运行 GC 时,它将释放应用程序无法访问的所有内容。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-02-15
        • 1970-01-01
        • 1970-01-01
        • 2013-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多