Как создать службу WCF, которая действует в очереди «Производитель\Потребитель»?

У меня есть служба WCF, к которой подключаются несколько клиентов и подписываются на события.

У меня также есть рабочий поток, который работает в фоновом режиме вместе с размещенной службой WCF и выполняет операции и помещает элементы в 'Producer\Consumer Queue'.

Как заставить службу WCF действовать, когда в очереди есть элементы, чтобы она могла извлечь элемент из очереди, проанализировать его и опубликовать сообщение для всех подписанных клиентов?

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

Я был бы признателен всем, кто мог бы ответить простым примером кода, если это возможно.


person John Miner    schedule 01.07.2012    source источник


Ответы (2)


Проще говоря, вам нужно событие, на которое ваша служба wcf может подписаться для события постановки в очередь из очереди и начать обработку сообщения после возникновения события. Для неуниверсальной очереди вы можете переопределить метод Enqueue, чтобы вызвать событие OnChanged.

public override void Enqueue(object obj)
{
    base.Enqueue(obj);
    OnChanged(EventArgs.Empty);
}

Подробнее о том, как вызвать событие из общей очереди, см. здесь

//from worker thread
queue.Enqueue(some_object);

//in wcf you could probably do something like this
queue.OnChanged +=  ProcessMessage;

public void ProcessMessage(object sender, EventArgs e)
{
     lock(lock_object)
     {
          var some_object = queue.Dequeue;
          //processing logic and broadcasting to client
     }
}
person Anand    schedule 01.07.2012
comment
да, но где служба WCF зарегистрируется для этого события? в конструкторе службы? и что произойдет, если событие возникнет, когда служба обрабатывает сообщение от одного из своих клиентов? это хорошее программирование? не похоже... - person John Miner; 02.07.2012
comment
Всякий раз, когда вы будете работать с несколькими потоками, обязательно возникнут условия гонки. Ответственность за это лежит на нас, программистах (или просто на отказе от многопоточного приложения). Если вы посмотрите достаточно внимательно, я использовал оператор блокировки при удалении элементов из очереди, чтобы избежать состояния гонки. Я не понимаю, какова ваша концепция хорошего программирования. - person Anand; 02.07.2012
comment
Чтобы ответить на ваш вопрос, где служба WCF зарегистрируется для этого события. Да, конструктор кажется хорошим местом. (На вашем месте я бы сделал очередь статической). Я также надеюсь, что ваш рабочий поток создан внутри вашей службы wcf. - person Anand; 02.07.2012

Вот это моя идея, она может быть не лучшей, но это начало. Для достижения желаемой функциональности для вашего сценария создайте две службы WCF. Первая из служб будет называться QueueService, которая в основном содержит вашу очередь и управляет ею. Второй сервис вызывает его PublisherService, он предназначен для того, чтобы получать уведомления от QeueService, когда новые элементы добавляются/удаляются из очереди. Для этого необходимо использовать дуплексные каналы (применить шаблон подписки на публикацию http://msdn.microsoft.com/en-us/library/ms752254.aspx), где PublisherService действует как клиент для QueueService. Теперь о ваших клиентах, которые будут использовать PublisherService... Я не уверен, какую технику вы использовали до сих пор. Используете ли вы дуплексные каналы или непрерывную потоковую передачу для получения данных из PublisherService? (http://blog.john-thiriet.com/en/2011/08/using-reactive-extensions-for-a-push-based-client-server-communication-with-silverlight-and-wcf/)

person Mihai H    schedule 01.07.2012