垃圾收集器和事件处理程序

一个简单的问题。 假设我有一个如下例所示的类。

class Subscriber { private Publisher publisher = new Publisher; public Subscriber() { publisher.SomeEvent += new EventHandler(OnEventFired); } private void OnEventFired(object sender, EventArgs e) { } } 

在程序的某个地方,我有一个看起来像这样的方法:

 public void DoSomething() { Subscriber subscriber = new Subscriber(); } 

我是否正确地期望这会导致内存泄漏,因为订阅者永远不会取消订阅发布者事件,从而导致他们都保持对彼此的强引用?

它不会导致泄漏 – GC可以毫无问题地处理循环引用。

但是,这意味着发布者将有效地引用订阅者,因此在发布者符合GC条件或者取消订阅该事件之前, 不能对订阅者进行垃圾回收。

如果在事件发布者的GC生命周期期间,可以存在任意大量的事件订阅者并且放弃而不被取消订阅,则这种悬空订阅将构成内存泄漏。 如果事件发布者在订阅者被放弃的时间附近有资格进行垃圾收集,或者在最坏的情况下,每个发布者都有可能被创建和放弃的有限数量的订阅者,则没有内存泄漏。

我对.net的一个不满是微软不支持事件清理。 这在vb.net中尤其令人讨厌,它确保更改“WithEvents”变量将正确生成正确的订阅和unsubsriptions,但是没有为IDisposable处理程序取消订阅对象持有的所有事件提供便利的方法。