如果我有一个仅注册了少数事件处理程序的应用程序(并且使用该事件的对象直到应用程序关闭才被处置),我真的需要担心取消注册那些处理程序吗?我能看到的唯一好的原因是,如果触发了您不必关心的事件(即,您为一个事件注册了多个处理程序),则可能会有一些额外的开销。还有其他理由吗?是否有人因为未注销事件而遇到重大问题?
如果我有一个仅注册了少数事件处理程序的应用程序(并且使用该事件的对象直到应用程序关闭才被处置),我真的需要担心取消注册那些处理程序吗?我能看到的唯一好的原因是,如果触发了您不必关心的事件(即,您为一个事件注册了多个处理程序),则可能会有一些额外的开销。还有其他理由吗?是否有人因为未注销事件而遇到重大问题?
Answers:
如果您已经A
发布了一个事件,并B
订阅了一个事件(处理程序),那么如果A
要生存的时间比更长,那就是不退订只是一个问题B
。基本上,事件订阅意味着A
仍然可以看到B
,因此可以防止对其进行垃圾回收,即使您忘记了它(也可能忘记了Disposed()
它),仍然可以在其上触发事件。
例如,如果A
是静态事件,则这是一个问题,并且您的应用程序在B
死后运行了一段时间……但是B
可以生存到A
,因此B
不会被垃圾回收。
重要的是要注意,有人可能会问以下问题:
如果B的寿命比A长得多,B会阻止A被垃圾收集吗?
答案是“否”。B在整个事件中都没有提及A;A将正常收集
B
没有A
通过事件引用;A
将正常收集。
许多人似乎认为,只有发布者的寿命超过订阅者时,取消订阅事件才是重要的。我不喜欢这种方法。不与发布者分离的事件订阅者对发布者和订阅者之外的实体的行为产生了一些讨厌的依赖。如果对发布者的引用保留的时间比预期的长,这将使订阅者以及订阅者拥有引用的任何对象保持活动状态。如果事件处理程序将大量废弃的对象互连在一起,但是对它们中的任何一个都没有实时引用,则所有对象都可以被垃圾收集器清除。但是,如果某个地方的某人意外地保留了对其中一个对象的引用,则可能会阻止其中的任何一个被垃圾回收。
恕我直言,主动删除事件处理程序比放弃事件处理程序并希望清理一切要好得多。除非可以肯定没有对发布者的意外引用,否则这种方法很可能“大部分”起作用,但会导致偶尔的内存泄漏。