悬空事件处理程序和内存泄漏:哪个方向?

时间:2013-08-31 22:38:22

标签: c# events memory handler memory-leaks

我不确定这样做是否可行,但这个问题与我在做一些研究时偶然发现的一个来源有关,我认为这是不正确的,我希望我可以在这里讨论。在http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/learning-memory-management/WPF-silverlight-pitfalls,Chris Farrell声明以下内容会导致内存泄漏:

...
Order newOrder = new Order(“EURUSD”, ...);

newOrder.OnPlaced += OrderPlaced;
m_PendingDeals.Add(newOrder);
...
void OrderPlaced(Order placedOrder)
{
  m_PendingDeals.Remove(placedOrder);
}

以下是:

  

OrderPlaced事件处理程序仍保留对Order的引用   我们订阅OnPlaced事件时的对象,以及   即使我们已删除,引用也会使Order对象保持活动状态   它来自收藏。犯这个错误很容易。

这个解释是否正确?

我会说它不是:据我所知,它是事件通知器,它保持对事件订阅者的函数指针的引用,从而保持对事件订阅者的引用,而不是相反。在这种情况下,Order是保持对处理类的引用,并且当删除该Order时,它实际上将从内存中正确清除,假设没有对该Order的其他引用。想法?

1 个答案:

答案 0 :(得分:1)

您的解释是正确的 - Order类的事件包含对OrderPlaced函数的引用。因此,在放置OrderPlaced实例之前,包含订阅的Order函数的实例无法进行GC。

订阅Order事件的对象实例不知道引用,因此不是潜在内存泄漏的原因。

以下是Jon Skeet回答的类似问题。

Why and How to avoid Event Handler memory leaks?