簡體   English   中英

C#我應該手動刪除我聲明的事件處理程序嗎?

[英]C# Should I manually remove the event handler I declared?

好的,舉一個例子:

  1. 我有UserControl A,UserControl B,UserControl C和一個Windows窗體。
  2. 此Windows窗體僅以UserControl A啟動。
  3. UserControl C有[Next]和[Back]按鈕。
  4. 比如說,UserControl A是用事件處理程序聲明的。 UserControl A中的一個函數實際上會引發事件調用以在UserControl C執行一個函數。
  5. 所以,在UserControl C,我必須添加

“UserControlA.OneFunction + = this.UserControlC_Function;”

  1. 如果我在UserControl C上單擊“下一步”按鈕,它將處理UserControl A並將新的UserControl B添加到Windows窗體。 但我從不手動刪除此事件處理程序。

UserControl A中的一個功能是調用者(聲明事件的地方)。
UserControl C中的一個功能是監聽器。

所以,這些是我的問題:

  • 我應該在UserControl A處理之前手動刪除處理程序嗎?
  • 此用戶控件A dispose是否會自動刪除之前聲明的處理程序?
  • 我應該在某處添加嗎?

“UserControlA.OneFunction - = this.UserControlC_Function;”

  1. 按照慣例,我們沒有。 並且由於在處置之后不應該調用任何事件,所以除非所討論的控制行為奇怪,否則不需要這樣做。
  2. 不,至少從反射器看不到這樣的代碼。

在這種情況下,您不需要刪除處理程序,因為表單外部的代碼都不會引用表單及其按鈕,因此整個對象圖將被垃圾回收。

這篇文章的答案非常好,可以解釋何時需要手動刪除事件處理程序以及何時不需要。

我是否需要在孤立之前從對象中刪除事件訂閱?

如果表單被釋放(假設沒有其他對象具有對相關對象的引用),則不會刪除事件處理程序的風險很小,但是在無法再訪問對象之前始終刪除事件處理程序是個好主意(即所有引用范圍的對象的變量都沒有這樣做可能會造成內存泄漏。

在你的情況下不是這種情況(如果我得到你所描述的內容,代碼會使它更清晰)問題是如果你將一個委托引用對象C附加到對象A上的事件然后放棄對C的訪問(例如為變量分配新值)。 然后C會一直閑逛,直到A被垃圾收集

如果事件發布者的內存生命周期不限於事件訂閱者的有效生命周期,則取消訂閱事件的失敗可能會導致內存泄漏。 如果不是因為這樣做的不幸麻煩,就沒有任何理由讓事件訂閱者被處理掉不取消訂閱所有事件,並且事件發布者被處理不會使所有事件訂閱無效。 然而,由於C#和VB都沒有提供任何方便的方法來做這些事情,因此必須平衡正確訂閱處理的麻煩與在許多情況下人們可以避免吝嗇的事實。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM