2013-08-23 2 views
0

J'ai donc un objet qui déclenche des événements et un service WCF hébergé dans un service Windows. Les événements déclenchés sont actuellement dans une classe dans le service Windows et le service WCF s'abonne à ces événements et lorsque les événements se déclenchent ils sont destinés à être un rappel au client pour informer le client que quelque chose s'est passé sur une autre partie de le service Windows.Echec du rappel WCF dû à l'initialisation de l'objet (Duplex)

Les problèmes sont que parfois les rappels fonctionnent et parfois ils ne le font pas. J'ai des vérifications pour voir s'il y a des clients à rappeler si ce n'est pas le cas. Je ne suis pas sûr de la meilleure façon de mettre en œuvre c'est parce que parfois les:

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

reçoit un rappel à d'autres moments il des exceptions sur ou est définie sur null l'événement à venir dans le service WCF vient d'une autre partie du service Windows (classe A) plutôt que depuis OperationContext.

En bref Comment puis-je configurer mon service WCF pour alerter les clients lorsque des événements se sont produits dans une autre partie de mon service Windows?

(Code Plus)

Avant de publier les événements que je fais un chèque comme si (Seuls les soins à publier lorsque nous avons des clients):

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

Je publierai tout ça comme ceci:

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

Répondre

0

Je trouve que les éléments suivants travaille juste pour obtenir un rappel et de déclencher des mises à jour aux clients dans ma boucle foreach.

D'abord, je suis en train appel au dernier abonné

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

Ensuite, plus loin sur la publication méthode que je fais une vérification rapide en essayant de le mettre à l'appel en cours de canal arrière, mais si cela échoue attrape juste un qui Je sais que c'est là:

 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]; 
      } 
     } 

Bien que ce soit des œuvres que je ne suis pas sûr que ce soit la meilleure façon de le faire.

Questions connexes