WCF уведомляет подписчиков асинхронно

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

Комментарии:

1. Кроме того, я единственный, кто думает, что WCF — это боль в шее? (Вы знаете, что я имею в виду под neck.)

2. Где ваша проблема в коде? Исключение или проблема с логикой (алгоритм)?

3. Если один из подписчиков мертв, то возникает исключение тайм-аута callback.Notify() . Из-за этого уведомление другим подписчикам задерживается.

4. Если вы не обработаете это исключение TimeoutException внутри этого метода, ForEach прервется, что-то вроде ожидания завершения другого процесса. Обрабатываете ли вы исключение внутри обратного вызова. Метод уведомления()?

5. Я могу справиться с этим TimeoutException , но это не предотвратит отложенное уведомление другим подписчикам.

Ответ №1:

Вы можете поместить это в пул потоков:

  ThreadPool.QueueUserWorkItem(o => callback.Notify(sData));
  

Просто имейте в виду, что это может засорить ваш пул потоков, когда у вас много плохих подписчиков. Вероятно, вы хотите перехватывать исключения и удалять обратный вызов при сбое.

Обновление: Если вы не хотите использовать .Затем вы можете либо создать собственный пул потоков, либо, например, использовать SmartThreadPool

Комментарии:

1. Это не очень хорошая идея, потому что вы, скорее всего, будете использовать потоки, которые должны использоваться механизмом WCF для обработки входящих запросов.