2009-09-28 63 views
-1

我正在使用.NET 1.1框架修復用戶控件組件。事件訂閱到一個靜態實例。如何確保GC

這個用戶控件有很多引用包裝COM資源的單例的實例。 他們訂閱來自此資源的活動。

我懷疑我們之所以會出現性能下降的原因是因爲即使它們各自的窗口消失,單例仍然保留對用戶控件類的引用。從而防止GC。

他們在其finalize方法中取消訂閱事件。 因此我懷疑有雞和雞蛋的問題。 finalize不會執行,因爲它們通過它們的事件訂閱被引用到更長壽命的Singleton中,從而阻止GC。

在用戶控件中,我應該執行事件取消訂閱以使其符合GC的條件?

我沒有擁有託管用戶控件的應用程序。

回答

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它進入了相當數量的細節。

+0

Woa。 Jon Skeet。我只是標記「正確答案」,然後嘗試一下:)謝謝 – Tormod 2009-09-28 08:15:59

+0

我做了一個簡單的winform,一個帶事件和用戶控件的單例。用戶控件在其load方法中訂閱singleton事件,並將委託實例保留在成員變量中以在dispose方法中運行 - =。但是,finalize方法中的斷點永遠不會執行。 我也嘗試將Winform中的Usercontrol引用設置爲null,並且首先在其上調用dispose()。即使用戶控件對象不再由winform或singleton引用,用戶控件對象也不會完成。我在錯誤的軌道上? – Tormod 2009-09-28 09:26:49

+0

我的測試解決方案的方法肯定是有缺陷的。即使在我停止引用Singleton之後,我也無法在Finalizer內部中斷或從Finalizer接收到跟蹤。 – Tormod 2009-09-28 09:36:15