不注销事件处理程序是不是很糟糕?

SwD*_*n81 64 c# events event-handling

如果我的应用程序只注册了几个事件处理程序(并且在应用程序关闭之前不会处理使用事件的对象),我是否真的需要担心取消注册这些处理程序?我能看到的唯一一个好理由是,如果事件被解雇你可能会有一些额外的开销,你不必关心(即你有多个处理程序注册到一个事件).还有其他好的理由吗?任何人都遇到重大问题,因为他们没有取消注册事件?

Mar*_*ell 82

如果您已经A发布事件和B订阅事件(处理程序),那么它只是不退订,如果一个问题A是要住了很多长于B.基本上,事件订阅意味着A仍然可以看到B,因此会阻止它被垃圾收集,并且即使您已经忘记它(也许Disposed()它),它仍会在其上触发事件.

例如,如果A是一个静态事件,这是一个问题,你的应用程序在B死后B会运行一段时间...但只会生存A,因此B不会被垃圾收集.

值得注意的是,有人可能会问以下问题:

如果B的寿命比A长很多,B会不会收集垃圾?

答案就是"不".B没有通过该事件提及A; A将照常收集

  • @Scott.不 - "B"在活动中没有提到"A"; `A`将照常收集. (5认同)
  • 我知道这是一个老帖子,我不知道它是否会被阅读,但如果B比A长寿,B会不会收集垃圾? (3认同)

sup*_*cat 16

许多人似乎认为,如果发布者要比订阅者更长,那么取消订阅事件是非常重要的.我不喜欢这种方法.不与发布者分离的事件订阅者对发布者和订阅者之外的实体的行为产生了一些讨厌的依赖性.如果对发布者的引用持续时间超过预期,则会使订阅者保持活动状态,以及订阅者持有引用的任何对象.如果大量的废弃对象通过事件处理程序互连,但它们中的任何一个都没有实时引用,则垃圾收集器可以清除所有对象.但是,如果有人在某处意外地保留对其中一个对象的引用,则可能会阻止其中的任何对象被垃圾收集.

恕我直言,主动删除事件处理程序比抛弃事件处理程序要好得多,并希望一切都得到清理.除非可以确定不存在对发布者的意外引用,否则这种方法可能"主要"起作用,但偶尔会导致内存泄漏.