事件订阅静态实例。如何确保GC

时间:2009-09-28 08:00:43

标签: c# .net winforms user-controls garbage-collection

我正在使用.NET 1.1框架修复用户控件组件。

此用户控件的许多实例引用包装COM资源的单例。 他们订阅了这个资源的事件。

我怀疑我们之所以具有降级性能是因为即使在各自的窗口消失之后,单例仍然保持对用户控件类的引用。从而阻止GC。

他们在finalize方法中取消订阅该事件。 因此,我怀疑鸡和蛋的问题。 finalize不会执行,因为它们是通过在较长寿的Singleton中的事件订阅引用的,从而阻止了GC。

我应该在用户控件中执行哪些事件取消订阅以使其符合GC的条件?

我不拥有托管用户控件的应用程序。

1 个答案:

答案 0 :(得分:1)

您应该在控件处理时取消订阅,确实。如果您无法自己轻松修改Dispose方法,则可以向Disposed事件添加事件处理程序:

ComSingleton.Foo += FooHandler;
this.Disposed += delegate { ComSingleton.Foo -= FooHandler; };

如果要使用匿名方法或lambda表达式订阅事件,则需要使用单独的局部变量,以便再次引用它:

EventHandler tmp = delegate { Console.WriteLine("Something happened"); };
ComSingleton.Foo += tmp;
this.Disposed += delegate { ComSingleton.Foo -= tmp; };

另一种方法是使用“弱事件处理程序” - 网上有很多关于此事的文章; here's one进入了相当多的细节。