2012-11-18 65 views
4

我想實現一個消息系統,我只是使用常規的.NET事件,但問題是發佈者的壽命比訂閱者長,發佈者持有對訂閱者的引用並阻止該事件被註銷。如何實現在用戶不再被引用時取消訂閱的事件?

我在尋找微弱的事件,但有很多不同的實現它們,我無法繞過他們的大腦。我想要簡單的東西。

此外,他們中的大多數在沒有引用時不立即註銷事件。我希望有一個系統在對象沒有更多引用或超出範圍時立即取消註冊事件。

我很好,沒有使用內置的事件語法糖,而是使用公共靜態類的排序,以促進整個努力。

我只希望能夠在一個類中引發一個事件,這個事件會調用所有那些訂閱的方法,這些方法會在用戶不再使用後立即自動取消註冊。

可以這樣做或者這已經存在框架中的某種方式嗎?

+1

請參閱[弱事件模式](http://msdn.microsoft.com/en-us/library/aa970850.aspx)(msdn)和[Weak Events in C#](http://www.codeproject.com) /文章/ 29922 /弱事件在C)(CodeProject) –

+3

'我在圍繞他們包裹我的大腦時遇到了麻煩。'我們都去過那裏,有時你只想做東西而不必學習東西新。然而,學習這個新事物幾乎總是正確的。短期痛苦等於長期收益。 –

+0

「防止事件未註冊」。什麼是「事件」? – Patrick

回答

0

如果我們定義一個委託:

public delegate void Callback (string s); 

如果出版商類包含一個事件:

public event Callback Notify; 

然後,用戶構造將包含註冊碼, 和它的類將包含訂閱該事件的「更新」方法:

class Subscriber 
{ 
    Publisher publisher; 

    public Subscriber (Publisher publisher) 
    { 
     this.publisher = publisher; 
     publisher.Notify += Update; 
    } 

    public void Update(string subjectState) 
    { 
    state = subjectState; 
    } 
} 

爲了改變該用戶從事件註銷時,它會死,我們需要實現一個終結其類:

~Subscriber() 
{ 
    if (publisher != null) 
    { 
    publisher.Notify -= Update; 
    } 
} 

這樣我們就可以肯定的是,用戶將不再被註冊事件。 想了解更多關於'Finalize'方法的信息,請閱讀這個偉大的article from the 'MSDN' magazine on "Garbage Collection"

+0

從終結器訪問另一個對象是*不是一個好主意 - 該對象可能不再存在。實施一次性模式並將未註冊的呼叫置於「真正」處理路徑中會更好。 –

+0

我不建議從終結器訪問此對象。當這個對象不再被引用時,垃圾收集器將調用這個finalize方法。只有垃圾收集器知道這個對象何時不再被引用。 – Boolean

+0

您正在訪問終結器中的'publisher'。 '發佈商'引用可能不再在終結器中有效 - 該對象本身可能已被清除。 –