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

时间:2009-06-30 04:28:33

标签: c# events event-handling

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

2 个答案:

答案 0 :(得分:80)

如果您A发布了一个事件,B订阅了一个事件(处理程序),那么只有在A将要生效的情况下才取消订阅只是一个问题比B长很多。基本上,事件订阅意味着A仍然可以看到B,因此会阻止它被垃圾收集,并且即使您已经忘记它也可能会在其上触发事件(也许{{}} 1}}它)。

例如,如果Disposed()是静态事件,并且您的应用在A死亡后运行了一段时间,则会出现此问题... B只会{ {1}},因此B不会被垃圾收集。

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

  

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

答案就是“不”。 B没有通过该事件提及A; A将按正常收集

答案 1 :(得分:14)

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

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