2011-07-07 136 views
4

我知道必須從事件IS取消訂閱。 我的問題來自於生成的代碼: 當您修改從VS編輯器的用戶界面,並添加事件處理程序的UI元素(例如: private void BtnSampleClick(object sender, EventArgs e)C#UI事件取消訂閱 - 必要?

在創建這個事件處理,VS添加此代碼該自動生成的private void InitializeComponent()代碼

this.btnSample.Click += new System.EventHandler(this.BtnSampleClick); 

問題是,VS不會在形式的Dispose方法自動添加退訂(this.btnSample.Click -= new System.EventHandler(this.BtnSampleClick);)。

通常我們應該在那裏添加它們嗎?如果沒有,這將泄漏到內存泄漏? 想檢查是否有VS不會自動執行取消訂閱的原因。即使我們不這樣做,也許表格是正確處理的?

感謝您幫助我在這件事情上削減一些光!

回答

6

這沒有完成,主要是因爲在這種情況下真的不是必需的。原因是您的表單正在訂閱由表單管理的對象的事件。從GC的角度來看,當對象(即:按鈕)被解除連接時,表單也將被解除連接(並關閉),所以不會有內存泄漏的機會。 .NET中的GC很聰明 - 像這樣的循環引用不是問題。

但是,取消訂閱活動仍然是一個很好的通用實踐。如果您在具有與正在進行訂購的對象無關的生命週期的對象上訂閱事件,則變得非常重要。如果具有事件的對象比用戶長得多,這尤其如此。這種情況往往會發生事件引起的內存泄漏。例如,如果您的Form訂閱了一個靜態實例上的事件,並且忘記取消訂閱,則表單將永遠不會被垃圾收集,因爲委託引用將通過事件訂閱使它「保持根源」。

+0

+1解釋這是因爲同步生命週期。 – Ergwun

1

是的,這是一個很好的做法,明確退訂。儘管它們可能導致內存泄漏,但只要它們沒有引用非託管對象,GC仍然可以在託管的環境中正確地確定和清除。

0

你不需要關心那件事。 Dot.NET框架有一個垃圾收集器(GC),它可以使用自己的原理自動處理(可能是當沒有引用剩下的對象時)。

這並不意味着你永遠不需要調用Dispose功能,在某些情況下,你刻意調用Dispose()方法,以使內存沒有用完,或當我們與本地的dll/Marshal類工作