不注销事件处理程序是否不好?


67

如果我有一个仅注册了少数事件处理程序的应用程序(并且使用该事件的对象直到应用程序关闭才被处置),我真的需要担心取消注册那些处理程序吗?我能看到的唯一好的原因是,如果触发了您不必关心的事件(即,您为一个事件注册了多个处理程序),则可能会有一些额外的开销。还有其他理由吗?是否有人因为未注销事件而遇到重大问题?

Answers:


89

如果您已经A发布了一个事件,并B订阅了一个事件(处理程序),那么如果A要生存的时间比更长,那就是不退订只是一个问题B。基本上,事件订阅意味着A仍然可以看到B,因此可以防止对其进行垃圾回收,即使您忘记了它(也可能忘记了Disposed()它),仍然可以在其上触发事件。

例如,如果A是静态事件,则这是一个问题,并且您的应用程序在B死后运行了一段时间……但是B可以生存到A,因此B不会被垃圾回收。

重要的是要注意,有人可能会问以下问题:

如果B的寿命比A长得多,B会阻止A被垃圾收集吗?

答案是“否”。B在整个事件中都没有提及A;A将正常收集


马克·马克斯 静态事件的处理程序如果在处置订阅服务器时没有注意的话,确实是臭名昭著的。
TheVillageIdiot

3
我知道这是一个老帖子,我不知道它是否会被阅读,但是如果B的寿命比A长得多,B会阻止A被垃圾收集吗?
Scott Chamberlain 2010年

5
@斯科特。否-B没有A通过事件引用;A将正常收集。
马克·格雷韦尔

18

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

恕我直言,主动删除事件处理程序比放弃事件处理程序并希望清理一切要好得多。除非可以肯定没有对发布者的意外引用,否则这种方法很可能“大部分”起作用,但会导致偶尔的内存泄漏。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.