为什么我的 C# 自定义事件没有引发?

发布于 2024-10-16 05:47:52 字数 1438 浏览 3 评论 0原文

这不是我第一次用 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");   
}

在订阅者.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

It's not the first time I've created a Custom Event in C#. It boggles my mind why it doesn't work in this simple case.

I have a Publisher with Subscribers. In my main program, I instantiated 1 publisher and 2 subscribers. When addNews is called, Subscribers should receive the event NewPublication:

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

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

In subscriber.cs I have:

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);
        }
    }
}

In Subscriber I have:

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);
}

It compiles, but when running, the event is never raised. Why not? How can I fix my code so that it does get raised?

What's really different from MSDN sample code:
http://msdn.microsoft.com/en-us/library/w369ty8x.aspx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

奢欲 2024-10-23 05:47:52

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

以下是您的 Subscriber 类应该如何工作:

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 类引入 Subscribe 方法,如下所示:

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

请注意,事件处理程序是附加的,但从未分离,这可能会导致您的 Publisher 类中的内存泄漏.NET 应用程序。当您不再需要事件处理程序时,始终使用 -= 运算符来分离它们(例如,在 WinForms 应用程序中,我通常在触发 FormClosed 事件时分离控件事件的事件处理程序)。 这里有一篇很好的文章解释了这一点深入了解,这里是另一篇演示内存泄漏检测的文章。

对于高级事件概念,您可能需要熟悉 F# 和响应式框架的事件模型(也没有内存泄漏),如 系列文章。

It appears that you actually have 2 newPublication events: one in Subscriber and one in Publisher. You're raising the one in Publisher, but the Subscribers only subscribe to their own event.

Here is how your Subscriber class should work:

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);
}

For the ease of use, you might want to introduce a Subscribe method to your Publisher class, like so:

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

Note that event handlers that are attached, but never detached and that can cause memory leaks in your .NET application. Always use the -= operator to detach event handlers when you no longer need them (for example in a WinForms application I usually detach the event handlers for control events when the FormClosed event is fired). Here is a good article that explains it in depth, and here is another one that demonstrates the detection of memory leaks.

For an advanced event concept you might want to familiarize yourself with F#'s and the Reactive Framework's event model (which are also free of memory leaks), as described in this series of articles.

篱下浅笙歌 2024-10-23 05:47:52

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

您需要做的示意性工作是:

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

将此代码放在这些类的实例化和对 AddNews() 的调用之间。

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

You've declared two distinct events. Your publisher instance and subscriber instances are not connected in any way. Hence raising the event in the publisher won't trigger the handlers in the subscribers.

What you need to do is schematically:

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

Place this code between instantiation of these classes and calls to AddNews().

Update: Hence the declaration of newPublication in the Subscriber class is completely useless and shall be removed from that class. If you need, you can pass the Publisher instance into a Subscriber's constructor to make the event wiring within the Subscriber. However, it's generally a good idea to keep event wiring code outside both event publishers and event subscribers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文