#c# #wcf #callback
#c# #wcf #обратный вызов
Вопрос:
Это моя служба WCF. Я хочу уведомлять нескольких подписчиков о некоторых обновлениях и делать это асинхронно. Как мне это сделать?
// Callback contract
public interface IMyServiceCallback
{
[OperationContract]
void Notify(String sData);
}
public class MyService:IMyService
{
List<IMyServiceCallback> _subscribers = new List<IMyServiceCallback>();
// This function is used to subscribe to service.
public bool Subscribe()
{
try
{
IMyServiceCallback callback = OperationContext.Current.GetCallbackChannel<IMyServiceCallback>();
if (!_subscribers.Contains(callback))
_subscribers.Add(callback);
return true;
}
catch
{
return false;
}
}
// this function is used to notify all the subsribers
// I want ForEach to be asynchronous.
public void OnGetMsg(string sData)
{
_subscribers.ForEach(
callback =>
{
if (((ICommunicationObject)callback).State == CommunicationState.Opened)
{
callback.Notify(sData); //THIS OPERATION
}
else
{
_subscribers.Remove(callback);
}
});
}
}
-
«MSDN: сбой клиента издателя / подписчика WCF» тесно связан с моей проблемой.
-
Я следил за мини-веб-трансляцией при создании этого сервиса.
Комментарии:
1. Кроме того, я единственный, кто думает, что WCF — это боль в шее? (Вы знаете, что я имею в виду под neck.)
2. Где ваша проблема в коде? Исключение или проблема с логикой (алгоритм)?
3. Если один из подписчиков мертв, то возникает исключение тайм-аута
callback.Notify()
. Из-за этого уведомление другим подписчикам задерживается.4. Если вы не обработаете это исключение TimeoutException внутри этого метода, ForEach прервется, что-то вроде ожидания завершения другого процесса. Обрабатываете ли вы исключение внутри обратного вызова. Метод уведомления()?
5. Я могу справиться с этим
TimeoutException
, но это не предотвратит отложенное уведомление другим подписчикам.
Ответ №1:
Вы можете поместить это в пул потоков:
ThreadPool.QueueUserWorkItem(o => callback.Notify(sData));
Просто имейте в виду, что это может засорить ваш пул потоков, когда у вас много плохих подписчиков. Вероятно, вы хотите перехватывать исключения и удалять обратный вызов при сбое.
Обновление: Если вы не хотите использовать .Затем вы можете либо создать собственный пул потоков, либо, например, использовать SmartThreadPool
Комментарии:
1. Это не очень хорошая идея, потому что вы, скорее всего, будете использовать потоки, которые должны использоваться механизмом WCF для обработки входящих запросов.