我们发现系统中的奇怪行为/性能问题太多次是由“死”事件引起的 - 在释放的对象上调用的事件。看起来您需要在注册新事件之前始终释放( - =)现有事件。这看起来是最佳实践,但我们如何在现有代码中检测到这种情况?是否有一个工具可以发现代码中有关释放事件的问题?
希望我的问题很明确,
由于
Adi Barda
答案 0 :(得分:2)
您可以使用event accessors来跟踪事件的注册或取消注册时间。
答案 1 :(得分:0)
避免这种情况的最简单方法是使用编译器。如果您只想一次允许一个代理,请不要将其声明为事件(本质上是多播),而是作为普通代理。
换句话说,而不是:
public event MyDelegateType MyEvent;
使用以下内容:
public MyDelegateType MyEvent;
然后,调用者不是使用+=
编写代理,而只是使用=
分配给代理,隐式删除前一个代理。
答案 2 :(得分:0)
看看这篇文章,它讨论了你的情况,并提供了一些可以分析代码的工具的链接。
答案 3 :(得分:0)
一如既往,要明确并忘记GC存在(具有讽刺意味)。做 - =并且睡得好。
替代方案,黑客,WeakReferences ..
答案 4 :(得分:0)
看起来您需要在注册新事件之前始终释放( - =)现有事件。
这有一个缺陷。在注册新处理程序之前,您不需要释放现有事件 - 有很多时候您希望有多个对象订阅单个事件源。这是一种常见且非常有用的做法。
当您完成收听事件时,问题通常不会取消订阅事件。当源和侦听器都未被引导时,GC将清除它,但在此之前,它可以防止某些对象被释放。
我遵循的一般经验法则是:
如果您可以轻松跟踪您想要订阅和取消订阅的时间(即:您有一个固定的生命周期,并且它比事件源的生命周期短),您应该适当地订阅和取消订阅。
如果您无法跟踪何时应取消订阅,例如,如果您的类或源对象的生命周期由于某种原因而不确定,或者可能需要在您将被处置之前处置来源,请使用{ {3}}