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

时间:2011-07-13 10:56:29

标签: c# events garbage-collection

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

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();
}

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

2 个答案:

答案 0 :(得分:16)

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

但是,这意味着发布者实际上会有一个对订阅者的引用,因此订阅者无法进行垃圾收集,直到发布者符合GC条件,或者取消订阅事件

答案 1 :(得分:2)

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

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