垃圾收集器和事件处理程序
本文关键字:事件处理 程序 收集器 | 更新日期: 2023-09-27 18:02:35
一个简短的问题。假设我有一个实现如下例中的类。
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"变量将正确地生成适当的订阅和取消订阅,但没有提供方便的方法让IDisposable处理程序取消订阅对象持有的所有事件。