一个简单的问题。假设我有一个如下例所示的类。
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();
}
我是否正确地期望这会导致内存泄漏,因为订阅者永远不会取消订阅发布者事件,从而导致他们都保持对彼此的强引用?
答案 0 :(得分:16)
它不会导致泄漏 - GC可以毫无问题地处理循环引用。
但是,这意味着发布者实际上会有一个对订阅者的引用,因此订阅者无法进行垃圾收集,直到发布者符合GC条件,或者取消订阅事件
答案 1 :(得分:2)
如果在事件发布者的GC生命周期中,可能存在任意大量的事件订阅者并且在没有取消订阅的情况下放弃,则这种悬空订阅将构成内存泄漏。如果事件发布者在订阅者被放弃的时候有资格进行垃圾收集,或者在最坏的情况下,每个发布者都有可能被创建和放弃的有限数量的订阅者,则没有内存泄漏。
我对.net的一个不满是微软不支持事件清理。这在vb.net中尤其令人讨厌,它确保更改“WithEvents”变量将正确生成正确的订阅和unsubsriptions,但没有为IDisposable处理程序取消订阅对象持有的所有事件提供便利的方法。