2012-02-06 59 views
7

有當一些訂閱的事件在我的課,或者我需要換行認購/ unsubsription的方法被通知的任何方式,例如:有什麼方法可以在訂閱事件/代理時得到通知?

public class MyClass : ISomeInterface 
{ 
    public event SomeEventHandler SomeEvent; //How do I know when something subscribes? 

    private void OnSomeEventSubscription(SomeEventHandler handler) 
    { 
      //do some work 
    } 

    private void OnSomeEventUnsubscription(SomeEventHandler handler) 
    { 
      //do some work 
    } 
} 

,而不是

public class MyClass : ISomeInterface 
{ 
    private SomeEventHandler _someEvent; 

    public void SubscribeToSomeEvent(SomeEventHandler handler) 
    { 
      _someEvent += handler; 

      //do some work 
    } 

    public void UnsubscribeFromSomeEvent(SomeEventHandler handler) 
    { 
      _someEvent -= handler; 

      //do some work 
    }  
} 

原因我問,因爲這個事件已經直接暴露在ISomeInterface上,但是這個特定的實現需要知道什麼時候訂閱/取消訂閱。

回答

10

您可以編寫自定義訪問器爲您的活動:

private SomeEventHandler _someEvent; 
public event SomeEventHandler SomeEvent 
{ 
    add 
    { 
     _someEvent += value; 
     Console.WriteLine("Someone subscribed to SomeEvent"); 
    } 
    remove 
    { 
     _someEvent -= value; 
     Console.WriteLine("Someone unsubscribed from SomeEvent"); 
    } 
} 
+1

請注意,使用此代碼事件訂閱不是線程安全的。實現這一點的簡單方法是將_someEvent標記爲事件。 – CodesInChaos 2012-02-06 10:41:00

+0

輝煌,謝謝! – GazTheDestroyer 2012-02-06 10:45:16

1

托馬斯已經回答了這一點,但想到我也想補充一點,你可能需要鎖定在添加任何關鍵部分去掉的部分,因爲事件訂閱從來沒有線程安全,即你不知道誰將連接到你或什麼時候。例如:

private readonly object _objectLock = new object(); 
    private SomeEventHandler _someEvent; 

    public event SomeEventHandler SomeEvent 
    { 
     add 
     {  
      lock(_objectLock) 
      { 
       _someEvent += value; 
       // do critical processing here, e.g. increment count, etc could also use Interlocked class. 
      } // End if 
     } // End of class 
     remove 
     { 
      lock(_objectLock) 
      { 
       _someEvent -= value; 
       // do critical processing here, e.g. increment count, etc could also use Interlocked class. 
      } // End if 
     } // End if 
    } // End of event 
+0

你忘記了包含'_someEvent'。如果它只是一個字段,你的代碼也不是線程安全的。 – CodesInChaos 2012-02-06 11:51:52

+0

是的你是對的 - 如果你將_someEvent聲明爲一個類字段事件,那麼C#4.0會給你一個隱式鎖定,所以如果它是「private event SomeEventHandler _someEvent」,那麼鎖定裏面的add/remove用於添加/刪除值不需要。 – Jeb 2012-02-07 10:02:31

相關問題