【问题标题】:Dangling event handlers and memory leaks: which way around? [closed]悬空事件处理程序和内存泄漏:哪种方式? [关闭]
【发布时间】:2013-08-31 22:38:21
【问题描述】:

我不确定这样做是否可以,但这个问题与我在做一些研究时偶然发现的一个来源有关,我认为这是不正确的,我希望我可以在这里讨论这个问题。在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 的其他引用。想法?

【问题讨论】:

  • 这是一个问答网站,不是一个开放的讨论论坛。
  • @MikeW 这似乎不是一个基于讨论的问题,即使他说“讨论”,而是澄清事件如何保留对委托实例的引用,因为他找到了一篇回答该问题的文章以一种看起来不合逻辑的方式。

标签: c# events memory handler memory-leaks


【解决方案1】:

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

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

这是 Jon Skeet 回答的类似问题。

Why and How to avoid Event Handler memory leaks?

【讨论】:

  • 好的,太好了!因此,可以肯定的是,消息来源所说的信息是完全不正确的,并且反过来:)。对不起,我提到了讨论,因为没有什么可讨论的。它更多的是关于“我想知道正确的解释是什么,它正在阅读这个让我感到困惑的来源”。
  • @user1610325 是的 - 我阅读了整篇文章本身以确保没有遗漏任何内容,但它肯定完全倒退了,因此不正确。我不会说本文的其余部分完全不正确,但我建议不要将其用作参考。不知道为什么这个问题被搁置,因为它是一个直接回答的问题,不受意见,但我想这没关系 - 你得到了答案。祝你好运!
猜你喜欢
  • 2011-01-13
  • 2012-10-29
  • 2012-05-31
  • 1970-01-01
  • 2012-07-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-07
  • 1970-01-01
相关资源
最近更新 更多