2011-02-06 41 views
1

這不是我第一次在C#中創建自定義事件。它令我難以置信,爲什麼它在這種簡單的情況下不起作用。爲什麼我在C#中的自定義事件沒有提出?

我有一個發佈者與訂閱者。在我的主程序中,我實例化了1個發佈者和2個訂閱者。當addNews被調用時,訂戶應接收事件NewPublication:

static void Main() 
{ 
    Publisher publisher = new Publisher(); 
    Subscriber subscriber1 = new Subscriber("John"); 
    Subscriber subscriber2 = new Subscriber("Jane"); 

    publisher.AddNews("custom event NewPublication"); 
} 

在subscriber.cs我:

​​

訂戶,我有:

private String m_Name; 
private event NewPublication newPublication; 


public Subscriber(String name) { 
    m_Name = name; 
    newPublication += new NewPublication(subscriber_newPublication); 
} 

public void subscriber_newPublication(Publisher fromPublisher, String Message) { 
    MessageBox.Show(m_Name + " is notified for " + Message); 
} 

它編譯,但是當運行,事件從未被提出。爲什麼不?我怎樣才能修復我的代碼,使其得到提升?

什麼是從MSDN示例代碼確實不同: http://msdn.microsoft.com/en-us/library/w369ty8x.aspx

回答

4

看起來你實際上有2個newPublication事件:一個在訂閱者中,一個在發佈者中。您正在發佈Publisher中的一個,但訂閱者只訂閱他們自己的活動。

這是你的用戶類應該是如何工作的:

private String m_Name; 
private Publisher m_Publisher; 

public Subscriber(String name, Publisher publisher) { 
    m_Name = name; 
    m_Publisher = publisher; 
    m_Publisher.newPublication += new NewPublication(subscriber_newPublication); 
} 

public void subscriber_newPublication(Publisher fromPublisher, String Message) { 
    MessageBox.Show(m_Name + " is notified for " + Message); 
} 

爲了方便使用,您可能希望引入訂閱方法你Publisher類,像這樣:

public Subscriber Subscribe(String name) 
{ 
    return new Subscriber(name, this); 
} 

注附加的事件處理程序,但從不分離,並可能導致.NET應用程序中的內存泄漏。當不再需要事件處理程序時,總是使用 - =運算符來分離事件處理程序(例如,在WinForms應用程序中,當FormClosed事件被觸發時,我通常會分離控制事件的事件處理程序)。 Here是一篇很好的文章,深入解釋了它,here是另一個演示檢測到內存泄漏的文章。

對於高級事件概念,您可能需要熟悉F#和Reactive Framework的事件模型(它們也沒有內存泄漏),如this系列文章中所述。

1

您已經聲明兩個不同事件。您的發佈者實例和訂閱者實例是以任何方式連接的而不是。因此,在發佈者中引發事件不會觸發用戶中的處理程序。

你需要做的是示意:

publisher.newPublication += subscriber1.subscriber_newPublication; 
publisher.newPublication += subscriber2.subscriber_newPublication; 

將這些類和調用的實例之間的代碼AddNews()

更新:因此類中的newPublication的聲明完全沒用,應從該類中刪除。如果需要,您可以將Publisher實例傳遞給Subscriber的構造函數,以使事件連線在Subscriber內。但是,將事件接線代碼保存在事件發佈者和事件訂閱者之外通常是一個好主意。

+0

但是,這不會連接兩個事件。由於委託是值類型,因此您所做的只是將subscriber1.newPublication和subscriber2.newPublication的事件處理程序複製到publisher.newPublication。添加到訂閱者的任何其他事件處理程序都不會顯示在發佈者中。 – ShdNx 2011-02-06 10:07:11

+0

@ShdNx嘿,對,我的意思是`subscriber_newPublication`實際上。感謝您注意錯誤。 – 2011-02-06 10:12:30

相關問題