2011-08-02 86 views
3

我有一些C#代碼更新對象的某些屬性。我有一個事件處理程序被定義來幫助我在更新過程完成時作出響應。不幸的是,我知道這個事件被多次解僱。我懷疑這是因爲事件處理程序被設置在錯誤的時間。目前,它正在建立類似如下:清除或檢查C中的事件處理程序#

​​

由於代碼的複雜性,我在追尋它應該設置的一個艱難的時刻。我想只設置它以前沒有設置的事件處理程序。正因爲如此,我想要做這樣的事情:

ClearEventHandlers(myObject); 

myObject.Update_Succeeded = null; 
myObject.Update_Succeeded += new EventHandler(myObject_Update_Succeeded); 

有沒有辦法來完成我想要?

謝謝!

回答

4

您應該能夠使用減法運算符等除去的處理程序如下

myObject.Update_Succeeded -= new EventHandler(myObject_Update_Succeeded); 

或者檢查這一種方式,如果你要刪除所有的事件處理程序疑問

How to remove all event handlers from a control

0

你最好在你的對象的初始化設置事件處理程序,即在你的構造函數中。

6

是的,您可以自定義事件的添加/刪除訪問器。 This article描述了這些訪問器。但是,你可以這樣做:

class MyClass 
{ 
    private EventHandler _myEvent; 

    public event EventHandler MyEvent 
    { 
     [MethodImpl(MethodImplOptions.Synchronized)] 
     add 
     { 
      _myEvent = (EventHandler)Delegate.Combine(_myEvent, value); 
     } 
     [MethodImpl(MethodImplOptions.Synchronized)] 
     remove 
     { 
      _myEvent = (EventHandler)Delegate.Remove(_myEvent, value); 
     } 
    } 

    public void ClearMyEvent() { 
     _myEvent = null; 
    } 
    ... 
} 
+0

我不會推薦這種方法。事件監聽器不應該自由地取消訂閱他們一無所知的其他事件監聽器。 – Groo

+0

@格羅 - 總的來說,我同意。但可能有時候需要有一種方法來清除所有聽衆。 – CodeNaked

+0

我必須承認我還沒有遇到這種情況。 BCL中沒有一個類遵循你描述的模式(在我迄今爲止有機會看到的任何開源庫中)。 – Groo

2

正確的方法應該是從每個事件分離處理程序後,你不再使用它:

public class MyObjectListener 
{ 
    private readonly MyObject _object; 
    public class MyObjectListener(MyObject obj) 
    { 
      _object = obj; 
      Attach(); 
    } 

    // adds event handlers 
    private void Attach() 
    { 
     obj.UpdateSucceeded += UpdateSuceededHandler; 
     obj.UpdateFailed += UpdateFailedHandler; 
    } 

    // removes event handlers 
    private void Detach() 
    { 
     obj.UpdateSucceeded -= UpdateSuceededHandler; 
     obj.UpdateFailed -= UpdateFailedHandler; 
    } 

    ... 
} 

您需要決定的唯一事情就是在哪裏調用Detach方法。例如,你可以把它在處理程序本身:

 private void UpdateSuceededHandler(object sender, Data args) 
    { 
     Detach(); 
     // do something when it succeeds 
    } 

    private void UpdateFailedHandler(object sender, Data args) 
    { 
     Detach(); 
     // do something when it fails 
    } 

或者,你可以允許MyObjectListener用戶告訴它不再需要聽取附加對象:

 public void StopListening() 
    { 
     Detach(); 
    } 

的引發事件的對象不應允許其偵聽器修改事件調用列表。每個事件偵聽器只應訂閱或取消訂閱自己的事件處理程序。