Обработка событий С# с участием подписчика издателя не работает

У меня есть класс издателя и класс подписчика. У класса издателя есть событие, и подписчик хочет выполнить один из своих собственных методов при возникновении этого события.

Вот мой класс издателя с его событием:

public delegate EventHandler<MyEventArgs> MyEventHandler(object sender, MyEventArgs args);
public class MyEventArgs : EventArgs
{
    public string Content { set; get; }
}

public class Publisher
{
    public event MyEventHandler MyCustomEvent;

    public void TriggerEvent()
    {
        if(MyCustomEvent!=null)
            MyCustomEvent(this, new MyEventArgs{ Content = "Geeee! This isn't working!" });
    }
}

А вот и подписчик:

class Subscriber
{
    static void Main(string[] args)
    {
        Publisher publisher = new Publisher();

        //hook the event to a method
        publisher.MyCustomEvent += (s, e) => delegate
        {
            PrintThis(e.Content);
        };

       //Do something to trigger the event    
        publisher.TriggerEvent();
    }
    static public void PrintThis(string content)
    {
        Console.Write(content);
    }
}

Издатель не должен знать о подписчике. Я хочу, чтобы подписчик мог выполнить свою функцию PrintThis, когда издатель вызывает событие. Но это не работает. Что я здесь делаю неправильно?


person user3655614    schedule 28.01.2015    source источник
comment
Что не работает?   -  person Enigmativity    schedule 28.01.2015
comment
Точка останова в функции PrintThis никогда не срабатывает. На консоли ничего не печатается.   -  person user3655614    schedule 28.01.2015


Ответы (1)


Вы неправильно определили обработчик событий.

Делай это так:

public delegate void MyEventHandler(object sender, MyEventArgs args);

Обратите внимание, что возвращаемый тип — void.

И тогда сам обработчик события должен быть:

    publisher.MyCustomEvent += (s, e) =>
    {
        PrintThis(e.Content);
    };

Также ваш метод TriggerEvent безопаснее, если он определен следующим образом:

public void TriggerEvent()
{
    var mce = MyCustomEvent;
    if (mce!=null)
    {
        mce(this, new MyEventArgs{ Content = "Geeee! This isn't working!" });
    }
}

В многопоточной среде обработчик MyCustomEvent может переключаться между проверкой null и вызовом.

person Enigmativity    schedule 28.01.2015
comment
О.. Это работает! Огромное спасибо :) В чем разница? Я имею в виду, что компилятор не выдавал никаких синтаксических ошибок. - person user3655614; 28.01.2015
comment
Компилятор довольно снисходителен, когда дело доходит до приведения от одного делегата к другому, если вы явно привели как delegate (что вы и сделали). Если бы вы убрали только ключевое слово delegate, вы бы увидели сообщение об ошибке. - person Enigmativity; 28.01.2015