2013-08-23 2 views
0

У меня есть объект, который вызывает события и службу WCF, размещенную в службе Windows.Ошибка обратного вызова WCF из-за не инициализации объекта (дуплекс)

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

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

call = OperationContext.Current.GetCallbackChannel<IRiskEoDWCFEvents>(); 

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

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

(Дополнительный код)

Перед публикацией из событий я чек, как это (только забочусь публиковать, когда у нас есть клиенты):

 private void Publish(EoDEvent eodListEvent, EoDItem item) 
     { 
      if (_EoDEventSubscribers == null || _EoDEventSubscribers.Count == 0) 
      { 
       //Cannot publish because we have no one listening 
       return; 
      } 
     ..... 

Тогда я публикую все это так:

  Thread myThread = new Thread(myObject => 
      { 

       lock (_SubscriberLock) 
       { 
        foreach (IRiskEoDWCFEvents callback in _EoDEventSubscribers) 
        { 
         if (callback.GetHashCode() != myObject.GetHashCode()) 
         { 
          Logging.WriteLine("Sending event to {0}", callback.GetHashCode()); 
          try 
          { 

           if (eodListEvent == EoDEvent.EoDComponentStarted) 
            callback.EoDComponentStarted(item); 
           else if (eodListEvent == EoDEvent.EoDComponentCompleted) 
            callback.EoDComponentCompleted(item); 
           ..... 
          } 
          catch (Exception ex) 
          { 
           FaultException faultex = ex as FaultException; 
           if (faultex == null) 
           { 
            Logging.WriteLine("Callback failed, removing {0}",     callback.GetHashCode()); 
            toRemove.Add(callback); 
           } 
          } 
         } 
        } 
        if (toRemove.Count > 0) 
        { 
         foreach (IRiskEoDWCFEvents cb in toRemove) 
         { 
          _EoDEventSubscribers.Remove(cb); 
         } 
        } 
       } 

      }); 
      myThread.Priority = ThreadPriority.Highest; 
      myThread.Start(call); 

ответ

0

Так что я считаю, что следующее работают только, чтобы получить обратный вызов и выпалить обновления для клиентов в моем цикле Еогеаспа.

Сначала я устанавливаю вызов последнего абонента

 public void Subscribe() 
     { 
     IRiskEoDWCFEvents callback = OperationContext.Current.GetCallbackChannel<IRiskEoDWCFEvents>(); 

     call = callback; 

     lock (_SubscriberLock) 
     { 
      if (!_EoDEventSubscribers.Contains(callback)) 
      { 
       Logging.WriteLine("Adding callback {0}", callback.GetHashCode()); 
       _EoDEventSubscribers.Add(callback); 
      } 
     } 
    } 

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

 if (_EoDEventSubscribers == null || _EoDEventSubscribers.Count == 0) 
     { 
      //Cannot publish because we have no one listening 
      return; 
     } 

     if (call == null) 
     { 
      try 
      { 
       call = OperationContext.Current.GetCallbackChannel<IRiskEoDWCFEvents>(); 
      } 
      catch 
      { 
       call = _EoDEventSubscribers[0]; 
      } 
     } 

Хотя это работает, я не уверен, что это лучший способ сделать это.

Смежные вопросы