2012-03-01 25 views
7

我有這樣的代碼:設置一個事件爲Null

public class SomeClass 
{ 
    int _processProgress; 
    public int ProcessProgress 
    { 
     get { return _processProgress; } 
     set 
     { 
      _processProgress = value; 
      if (ProcessProgressChanged != null) 
       ProcessProgressChanged(value); 
     } 
    } 

    public delegate void ProcessProgressChangedEventHandler(int progressPercentage); 
    public event ProcessProgressChangedEventHandler ProcessProgressChanged; 

    public void ClearProcessProgressChangedEvent() 
    { 
     this.ProcessProgressChanged = null; 
    } 
} 

請問它退訂ProcessProgressChanged事件,當我稱之爲ClearProcessProgressChangedEvent()方法所有的方法?

我的代碼是在C#中,框架4,構建在VS2010 Pro中,項目在Winforms中。

請幫助。提前致謝。

+2

此問題不重複。在那個問題中,他們詢問如何將對象註冊爲空 - 即註冊到事件中。他們詢問有關將事件本身設置爲空的問題。 – Wes 2017-02-22 15:30:51

回答

14

那麼,它將有效地清除用戶列表,是的(通過將底層委託字段設置爲null) - 以便下次設置ProcessProgress時,不會調用任何處理程序。這並不是真的將事件設置爲null - 它將底層字段設置爲null。只是C#編譯器使用單個聲明創建事件(訂閱/取消訂閱方法對)和字段(存儲處理程序)。

您可能會發現我的article about events and delegates有用。

請注意,您的事件提升代碼當前不是線程安全的。我不知道是否必須或沒有,但你可能要使用到考慮

set 
{ 
    _processProgress = value; 
    var handlers = ProcessProgressChanged; 
    if (handlers != null) 
    { 
     handlers(value); 
    } 
} 

這樣,你不會得到一個NullReferenceException如果最後的處理程序是退訂在法律上無效後檢查之前的調用。

+1

謝謝,再次感謝_thread-safe tip_。 – 2012-03-01 09:15:18

+0

喬恩,你會碰巧知道如果訂閱匿名代理到事件,然後通過將事件分配給null來清除事件可以防止垃圾收集在例如lambda表達式中引用的對象上? – Apelsin 2013-05-18 02:40:06

+1

@Apelsin:你必須舉一個更具體的例子,說實話 - 可能是一個新的問題。但是如果事件的基礎字段設置爲空,我看不到會阻止垃圾回收。 – 2013-05-18 06:59:19

3

是的,它會取消訂閱活動中的所有人。有一個(有點間接恕我直言)參照本here

當所有用戶都從事件退訂,在發佈類的事件 實例設置爲null