【问题标题】:best practice to manage an EventAggregate when a form is disposed处置表单时管理 EventAggregate 的最佳实践
【发布时间】:2015-12-13 09:17:16
【问题描述】:

给你一个概念性问题:

我已经实现了一个 Winform 程序,它大量使用多线程(等待/异步),并且基于一个 MDI 表单,该表单具有一个停靠控件和许多可以打开/关闭的窗口。其中一些只是在关闭时隐藏,而另一些则被丢弃

我开始创建暴露普通事件的业务类,但很快我意识到由于内存泄漏我会做噩梦(记得在关闭表单时将每个订阅的事件删除到其他组件,等等......)并且我实现了一个使用自定义事件聚合器的更好解决方案

这样的事件聚合器使用 Wea​​kReference,所以我认为我不必记得清理每个聚合事件订阅者,问题是当我关闭我的表单(并且它们被处理)时,WeakReference 仍然显示那些表单are Alive,这是因为 Forms 还没有被 GarbageCollected,这导致订阅者仍然可以接收已发布的事件。

现在我想知道处理此类问题的最佳方法是什么,目前我的选择是:

  1. 当我在 EventAggregate 中通知一个事件时,我可以检查接收器是否为 IDisposable 并检查它是否为 System.Windows.Forms.Control,然后检查其“IsDisposed”/“IsDisposing”属性

  2. 在每个事件处理程序中检查表单是否被释放/释放,以防止在释放的对象上做任何事情

  3. 在每个 Form 上覆盖 OnDispose 并强制 GC.Collect,以便我的弱引用向订阅者发出已死的信号

  4. 在每个表单上覆盖 OnDispose 并取消注册我的表单已完成的任何订阅

1 和 2 很丑,3 和 4 更好,但我希望我能错过一些其他方式来以更好的方式实现这一点,有什么建议吗?

【问题讨论】:

    标签: c# winforms eventaggregator


    【解决方案1】:

    首选方式(恕我直言)将是 #4 的变体,而不是使用 OnDispose() 使用 OnFormClosed() 它更可靠一点,以防万一您的来电者关闭了论坛但从未处理它。

    protected override void OnFormClosed(FormClosedEventArgs e)
    {
         UnregiesterEvents();
         base.OnFormClosed(e);
    }
    

    【讨论】:

    • 好的,谢谢,对表单使用 OnFormClosed 可能会更好,(但即使对于没有该方法的其他类型的控件,我也需要它)。无论如何,这并没有改善我的选择,所以我仍然希望有其他解决方案(如果有的话)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 2013-08-25
    • 1970-01-01
    • 2015-09-02
    相关资源
    最近更新 更多