C#我应该手动删除我声明的事件处理程序吗?

时间:2011-08-03 12:21:44

标签: c# event-handling

好的,在这里举个例子:

  1. 我有UserControl A,UserControl B,UserControl C和一个Windows窗体。
  2. 此Windows窗体仅以UserControl A启动。
  3. UserControl C有[Next]和[Back]按钮。
  4. 说,用一个事件处理程序声明UserControl A. UserControl A中的一个函数实际上会引发事件调用以在UserControl C执行一个函数。
  5. 因此,在UserControl C,我必须添加
  6.   

    “UserControlA.OneFunction + = this.UserControlC_Function;”

    1. 如果我在UserControl C上单击“下一步”按钮,它将处理UserControl A并将新的UserControl B添加到Windows窗体。但我从不手动删除此事件处理程序。
    2. UserControl A中的一个功能是调用者(声明事件的地方) UserControl C中的一个功能是监听器。

      所以,这些是我的问题:

      • 我应该在UserControl A处理之前手动删除处理程序吗?
      • 此User Control A dispose会自动删除之前声明的处理程序吗?
      • 我应该在某处添加吗?
        

      “UserControlA.OneFunction - = this.UserControlC_Function;”

5 个答案:

答案 0 :(得分:3)

  1. 按惯例,我们没有。并且由于处理后不会调用 事件,因此除非有问题的控件表现得很奇怪,否则无需这样做。
  2. 否。至少从反射器中看不到这样的代码。

答案 1 :(得分:2)

在这种情况下,您不需要删除处理程序,因为表单外部的代码都没有引用表单及其按钮,因此整个对象图将被垃圾回收。

答案 2 :(得分:2)

这篇文章的答案非常适合解释何时需要手动删除事件处理程序以及何时不需要。

Do I need to remove event subscriptions from objects before they are orphaned?

答案 3 :(得分:0)

如果表单被释放(假设没有其他对象有对相关对象的引用),则不会删除事件处理程序的风险很小,但是在对象侦听不能再进行之前总是删除事件处理程序是个好主意到达(即引用范围的对象的所有变量)不这样做会造成内存泄漏。

在您的情况下情况并非如此(如果我得到您所描述的内容,代码会更清晰) 问题在于,如果将对象引用对象C附加到对象A上的事件,然后放弃对C的访问(例如,为变量分配新值)。然后C会一直闲逛,直到A被垃圾收集

答案 4 :(得分:0)

如果事件发布者的内存生命周期不限于事件订阅者的有效生命周期,则取消订阅事件的失败可能会导致内存泄漏。如果不是因为这样做的不幸麻烦,就没有任何理由让事件订阅者被处理掉不取消订阅所有事件,并且事件发布者被处理不会使所有事件订阅无效。既然C#和VB都没有提供任何方便的方法来做这些事情,那么,人们必须平衡正确的订阅处理的麻烦,以及在许多情况下人们可以躲避它的事实。