【问题标题】:C# Explicitly Removing Event HandlersC# 显式删除事件处理程序
【发布时间】:2010-11-14 22:43:15
【问题描述】:

我想知道将对象设置为 null 是否会清除附加到对象事件的任何事件处理程序...

例如

Button button = new Button();
button.Click += new EventHandler(Button_Click);
button = null;

button = new Button();
button.Click += new EventHandler(Button_Click);
button = null;

等等……

这会导致内存泄漏吗?

【问题讨论】:

    标签: c# events memory-leaks garbage-collection


    【解决方案1】:

    如果在任何地方都没有其他对button 的引用,那么这里就不需要删除事件处理程序以避免内存泄漏。事件处理程序是单向引用,因此仅当具有事件的对象长期存在时才需要删除它们,并且您希望避免 处理程序(即具有处理程序方法的对象)的寿命比它们长应该。在您的示例中,情况并非如此。

    【讨论】:

    • 这是否意味着应用程序栏的事件处理程序也不需要显式删除(例如 statechanged)?
    • 这是相反的情况。 AppBar 是一个长期存在的对象,只要 AppBar 处于活动状态,事件处理程序至少会保持委托引用的对象处于活动状态,而您可能不希望这种情况发生。另一方面,如果处理程序是拥有该栏的窗口上的方法,则无关紧要。
    【解决方案2】:

    总结:当事件源/发布者长期存在而订阅者不是时,您需要显式取消订阅。如果事件源超过订阅者,所有注册的订阅者都被事件源保持“活动”(不被 GC 收集),除非他们取消订阅(并从事件发布者的通知列表中删除对自己的引用)

    这也是 Is it necessary to explicitly remove event handlers in C# 并且有一个很好的标题 n 答案。所以投票结束。

    【讨论】:

    • 我看到了那个问答。我的问题要直截了当,需要一个更简单的答案。
    【解决方案3】:

    查看讨论here under "The final question: do we have to remove event handlers?"

    结论:你应该删除 当他们到达时来自事件的代表 在课堂之外;即当 您订阅外部事件,您 应该在您结束订阅时 完成。不这样做将保留 你的对象比 必要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-22
      相关资源
      最近更新 更多