1

这不是我第一次在 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 我有:

public delegate void NewPublication(Publisher fromPublisher, String Message);

public class Publisher {

    private List<String> newsList = new List<String>();
    public event NewPublication newPublication;

    public void AddNews(String news) {
        newsList.Add(news);

        if (newPublication != null)
        {
            newPublication(this, news);
        }
    }
}

在订阅者中,我有:

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 回答 2

4

看来您实际上有 2 个 newPublication 事件:一个在订阅者中,一个在发布者中。您在发布者中提出了一个,但订阅者只订阅他们自己的事件。

以下是您的订阅者类的工作方式:

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 事件时分离控制事件的事件处理程序)。是一篇深入解释它的好文章,是另一篇演示内存泄漏检测的文章。

对于高级事件概念,您可能需要熟悉 F# 和 Reactive Framework 的事件模型(它们也没有内存泄漏),如系列文章中所述。

于 2011-02-06T10:00:51.187 回答
1

您已经声明了两个不同的事件。您的发布者实例和订阅者实例没有以任何方式连接。因此,在发布者中引发事件不会触发订阅者中的处理程序。

您需要做的是示意性地:

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

将此代码放在这些类的实例化和对AddNews().

更新:因此类中的声明newPublication完全Subscriber没用,应从该类中删除。如果需要,可以将Publisher实例传递给Subscriber的构造函数,以在Subscriber. 但是,将事件连接代码保留在事件发布者和事件订阅者之外通常是一个好主意。

于 2011-02-06T09:58:01.143 回答