2015-11-04 48 views
0

有人可以在提出事件時解釋下面的語句的重要性。c#中的邏輯OnEventReached方法

EventHandler<ThresholdReachedEventArgs> handler = ThresholdReached; 

由於我們簡單地分配閾值事件到處理器,爲什麼我們不能只是簡單地調用像ThresholdReached(這一點,E)

protected virtual void OnThresholdReached(ThresholdReachedEventArgs e) 
    { 
     EventHandler<ThresholdReachedEventArgs> handler = ThresholdReached; 
     if (handler != null) 
     { 
      handler(this, e); 
     } 
    } 
    public event EventHandler<ThresholdReachedEventArgs> ThresholdReached; 

回答

4

有了這個第一線,從多比賽條件保護線程應用程序

想象一下,如果某個其他線程在您檢查它是否爲空之後取消訂閱了事件。

並且檢查null是必需的,因爲沒有任何處理程序的事件爲null,您將通過調用此類事件來獲取NullReferenceException。

所以要精確。

此代碼不檢查空和可能引發的NullReferenceException:

protected virtual void OnThresholdReached(ThresholdReachedEventArgs e) 
{ 
    ThresholdReached(this, e); 
} 

這是危險的,由於可能的競爭條件,也可能會拋出異常:

protected virtual void OnThresholdReached(ThresholdReachedEventArgs e) 
{ 
    if (ThresholdReached != null) 
     ThresholdReached(this, e); 
} 

EDIT(以更好地解釋局部變量的行爲):

具有此分配可創建維護其狀態的本地事件副本。因此,如果在事件本地副本中取消訂閱的任何線程在整個剩餘的方法調用中保持不變。換句話說,代理的行爲就像複製一個不像複製引用的結構一樣。

下面的代碼將打印文本:

 // let's assume ThresholdReached is null 
     ThresholdReached += MyHandler; 
     EventHandler<ThresholdReachedEventArgs> localCopy = ThresholdReached ; 
     ThresholdReached -= Program_SthEvent; 
     if (localCopy != null) 
      Console.WriteLine("we have a copy!"); 

注意如何localCopy保持狀態和價值;

+0

很好地陳述。做得好。 – Enigmativity

+0

部分回答了我的問題。但是,如果是這樣的話,那麼下面的說明如何幫助我們解決競爭條件並確保它不會拋出任何異常?畢竟這只是一項任務。 EventHandler handler = ThresholdReached; – DivideByzero

+0

編輯我的答案,以更好地解釋什麼作業 – pg0xC