C# - 跟踪和追踪的最佳方式是什么?避免死亡事件

时间:2009-11-05 16:09:33

标签: c# events

我们发现系统中的奇怪行为/性能问题太多次是由“死”事件引起的 - 在释放的对象上调用的事件。看起来您需要在注册新事件之前始终释放( - =)现有事件。这看起来是最佳实践,但我们如何在现有代码中检测到这种情况?是否有一个工具可以发现代码中有关释放事件的问题?

希望我的问题很明确,

由于

Adi Barda

5 个答案:

答案 0 :(得分:2)

您可以使用event accessors来跟踪事件的注册或取消注册时间。

答案 1 :(得分:0)

避免这种情况的最简单方法是使用编译器。如果您只想一次允许一个代理,请不要将其声明为事件(本质上是多播),而是作为普通代理。

换句话说,而不是:

public event MyDelegateType MyEvent;

使用以下内容:

public MyDelegateType MyEvent;

然后,调用者不是使用+=编写代理,而只是使用=分配给代理,隐式删除前一个代理。

答案 2 :(得分:0)

看看这篇文章,它讨论了你的情况,并提供了一些可以分析代码的工具的链接。

http://msdn.microsoft.com/en-us/library/ee658248.aspx

答案 3 :(得分:0)

一如既往,要明确并忘记GC存在(具有讽刺意味)。做 - =并且睡得好。

替代方案,黑客,WeakReferences ..

答案 4 :(得分:0)

  

看起来您需要在注册新事件之前始终释放( - =)现有事件。

这有一个缺陷。在注册新处理程序之前,您不需要释放现有事件 - 有很多时候您希望有多个对象订阅单个事件源。这是一种常见且非常有用的做法。

当您完成收听事件时,问题通常不会取消订阅事件。当源和侦听器都未被引导时,GC将清除它,但在此之前,它可以防止某些对象被释放。

我遵循的一般经验法则是:

如果您可以轻松跟踪您想要订阅和取消订阅的时间(即:您有一个固定的生命周期,并且它比事件源的生命周期短),您应该适当地订阅和取消订阅。

如果您无法跟踪何时应取消订阅,例如,如果您的类或源对象的生命周期由于某种原因而不确定,或者可能需要在您将被处置之前处置来源,请使用{ {3}}