Подписаться на события в сервисе WCF - PullRequest
11 голосов
/ 08 октября 2009

У меня есть необходимость создавать отчеты в реальном времени о функциональности службы WCF.Служба размещается в приложении Windows самостоятельно, и мое требование состоит в том, чтобы сообщать «в прямом эфире» хост-приложению, когда клиент вызывает определенные методы.

Первоначально я думал о публикации: «NotifyNow "в сервисном коде и подпишитесь на событие в моем вызывающем приложении, но это не представляется возможным.В своем сервисном коде (реализация, а не интерфейс) я попытался добавить следующее

public delegate void MessageEventHandler(string message);
public event MessageEventHandler outputMessage;

void SendMessage(string message)
{
    if (null != outputMessage)
    {
        outputMessage(message);
    }
}

и вызывать метод SendMessage всякий раз, когда мне нужно уведомить приложение хоста о каком-либо действии.(Это основано на том, что я помню об этом виде взаимодействия между формами в приложении winforms, и моя память, возможно, подвела меня здесь ...)

Когда я пытаюсь подключить обработчик событий вхотя мой хост, похоже, не может понять, как присоединиться к событиям ... Мой код хостинга (в двух словах)

service = new ServiceHost(typeof(MyService));
service.outputMessage += new MyService.MessageEventHandler(frm2_outputMessage);
  // the above line does not work!
service.Open();

(завернутый в try / catch).

Может ли кто-нибудь помочь, либо рассказав мне, как заставить этот подход работать, либо указав мне лучший способ.

TIA

Ответы [ 3 ]

11 голосов
/ 08 октября 2009

Сервисная переменная является экземпляром ServiceHost, а не вашей реализацией сервиса. Попробуйте что-то вроде:

MyService myService = new MyService();
myService.outputMessage += new MyService.MessageEventHandler(frm2_outputMessage);
host = new ServiceHost(myService);
11 голосов
/ 09 октября 2009

Сегодня утром я провел еще несколько исследований и нашел гораздо более простое решение, чем было изложено выше. Основным источником информации была эта страница , но она обобщена здесь.

1) в классе обслуживания добавьте следующий (или аналогичный) код ..

public static event EventHandler<CustomEventArgs> CustomEvent;

public void SendData(int value) 
{       
    if (CustomEvent != null)
        CustomEvent(null, new CustomEventArgs());
}

Важный момент - сделать событие статичным, иначе у вас не будет возможности его поймать.

2) Определить класс CustomEventArgs, например ...

public class CustomEventArgs : EventArgs
{
    public string Message;
    public string CallingMethod;                        
}

3) Добавьте код вызова в каждый метод службы, в которой вы заинтересованы ...

public string MyServiceMethod()
{
    SendData(6);
}

4) Создайте ServiceHost как обычно и подключитесь к событию.

ServiceHost host = new ServiceHost(typeof(Service1));
Service1.CustomEvent += new EventHandler<CustomEventArgs>(Service1_CustomEvent);
host.Open();

5) Обрабатывать сообщения о событиях, которые передаются оттуда к хосту.

1 голос
/ 08 октября 2009

Вы, похоже, создаете экземпляр класса ServiceHost по умолчанию:

service = new ServiceHost(typeof(MyService));
              ***********
service.outputMessage += new MyService.MessageEventHandler(frm2_outputMessage);
  // the above line does not work!

и я очень сомневаюсь, что у обработчика событий будет свойство outputMessage.

Если вы не создаете экземпляр своего собственного хоста пользовательских служб, что-то вроде этого:

class MyCustomServiceHost : ServiceHost
{
  ...... your custom stuff here ......
}

service = new MyCustomServiceHost(typeof(MyService));
              *******************
service.outputMessage += new MyService.MessageEventHandler(frm2_outputMessage);

??

Марк

...