2010-08-26 45 views
5

我有一個窗體,其中我動態加載多個用戶控件。我處理每個控件的事件。用事件處理程序動態加載用戶控件 - 取消註冊

UserControl userControl1 = LoadControl("control.ascx") as UserControl; 
userControl1.Event += new ControlEventHandler(userControl_Event); 
this.Panel.Controls.Add(userControl1); 

UserControl userControl2 = LoadControl("control.ascx") as UserControl; 
userControl2.Event += new ControlEventHandler(userControl_Event); 
this.Panel.Controls.Add(userControl2); 

... 

現在,當我得到的面板上擺脫控制的,我只是做了

this.Panel.Controls.Clear(); 

是否清除()函數取擺脫事件的護理或我應該做

foreach(Control control in this.Panel.Controls) 
{ 
    UserControl userControl = control as UserControl; 
    if(userControl != null) 
    { 
     userControl -= userControl_Event; 
    } 
} 

之前我清除()面板的內容?

基本上,我正在尋找一種方式來動態加載用戶控件,並處理他們的事件,而不會造成泄漏,當我擺脫他們。

謝謝!

編輯: 因爲我的控件在頁面中的Page_Init事件創建(每次,因爲它們是動態加載),是正確地說,他們的壽命長度不能大於頁面的壽命? 從我所瞭解的情況來看,該控件在發佈後不存在。每次創建一個新的。因此,我不應該註銷事件,因爲它在下一頁加載時甚至不存在。那是對的嗎?

回答

5

該頁面將堅持動態實例化控件的引用集合被清除後,也將阻止這些控件從收集到該頁面本身收集。

在這種特殊情況下,這可以很好地工作,因爲頁面的壽命很短。

但是,如果這是一個Windows窗體應用程序,那麼內存將有效泄露,直到表單被釋放。

一般來說,當您釋放事件發生的對象時,取消訂閱您的事件是一個好主意,因爲這是絕大多數.net內存泄漏的來源。

0

垃圾收集器應該能夠收集他們沒有你讓他們註銷

0

說出動態加載的usercontrols的使用壽命不能超過它所屬的頁面的壽命是正確的。但是,在從頁面控件集合中刪除Web控件並將其分配給例如會話變量的情況下,我們不能說這是真的,可能會導致Web控件的壽命比頁面更長。所以它並不總是正確的。

如果您使用短生命的方法訂閱長壽命對象的事件(例如單例對象或與應用程序一起存儲的對象,會話和緩存),您應該取消訂閱事件對象(如頁面,用戶控件或Web控件等)。

例如

UserControl uc = LoadControl("control.ascx") as UserControl; 
SomeObject so=Session["SomeObject"] as SomeObject; 
If(so!=null) 
{ 
    so.SomeEvent += new SomeEventHandler(uc.SomeMethod); 
} 

這應該是從不會引起了內存泄漏的事件退訂。

最後你不必擔心在你的情況下注冊的事件。他們將被垃圾收集器收集。

0

您在面板中調用controls.Clear的事實足以證明您還應註銷事件。

爲此,您可以使用重寫的Clear方法中的未註冊代碼創建您自己的控件集合,而不是使用重寫的Controls屬性獲取器返回的使用您的新集合創建自己的面板。

相關問題