我应该只使用事件聚合器来防止内存泄漏吗?

时间:2011-07-17 19:00:57

标签: c# events memory-leaks prism eventaggregator

我们考虑使用Prism event aggregator来减少因事件引用而导致的内存泄漏。

  1. 这本身就是使用此模式的正当理由吗?其他好处现在对我们来说并不感兴趣。我们计划在模型组件之间使用它而不是UI。

  2. 我们的问题是一些开发人员忘记取消注册事件。我看到Prism有一种使用弱引用的味道,但它有limitations。其他风味强制显示Unsubscribe(),这又可以被遗忘。那怎么更好?

1 个答案:

答案 0 :(得分:6)

  

我们的问题是一些开发人员忘记取消注册事件

如果这是您的问题,切换到Prism事件聚合器(或使用任何其他实现)将无法改善。

将一个新的,非平凡的使用模式的新依赖项添加到一个混乱的情况下根本不会整理它。

您需要的是清理您的代码。

我建议使用静态分析工具,例如fxCop(又名代码分析),GendarmeNDepend,而不是新的代码库。所有这些都能够检测到某些事件没有被解开或IDisposable未正确实现的情况。

使用静态分析,您可以冷静地识别需要清理的代码。投入使用内存探查器(如dotTrace Memory),您将能够找到最严重的违法者,并及时清理它们。

更新

回答下面评论中的问题:

  

您认为什么是确保事件不被取消的良好模式?

在很难确保所有事件都被取消订阅时 - 但考虑到事件的实现方式(详见CLR via C#),您可以通过确保丢弃所有事件订阅来作弊。

而不是

public event EventHandler<Fu> FuBar;

自己处理事件订阅,如下所示:

public event EventHandler<Fu> FuBar {
    add { mFuBar += value; }
    remove { mFuBar -= value; }
}

private EventHandler<Fu> mFuBar;

然后,在您的课程上实施IDisposable,并在您的Dispose()方法集mFuBarnull中,弃用订阅。然后,FxCop(以及其他工具)可以告诉您是否未能处理该类。