2009-08-06 6 views
14

J'ai une application cliente qui essaie toutes les 10 secondes d'envoyer un message via un service Web WCF. Cette application client sera sur un ordinateur à bord d'un navire, qui, nous le savons, aura une connexion Internet inégale. Je voudrais que l'application essaie d'envoyer des données via le service, et si ce n'est pas le cas, de mettre en file d'attente les messages jusqu'à ce qu'ils puissent les envoyer via le service.Récupération à partir d'une exception CommunicationObjectFaultedException dans WCF

Afin de tester cette configuration, je démarre l'application client et le service Web (sur ma machine locale), et tout fonctionne correctement. J'essaye de simuler la mauvaise connexion internet en tuant le service web et en le redémarrant. Dès que je tue le service, je commence à obtenir CommunicationObjectFaultedExceptions - ce qui est attendu. Mais après avoir redémarré le service, je continue d'obtenir ces exceptions. Je suis assez sûr qu'il y a quelque chose que je ne comprends pas sur le paradigme du service Web, mais je ne sais pas ce que c'est. Quelqu'un peut-il donner des conseils sur la faisabilité de cette configuration et, si oui, comment résoudre ce problème (c.-à-d. Rétablir le canal de communication avec le service Web)?

Merci!

Klay

Répondre

33

proxy service à la clientèle ne peuvent pas être réutilisés une fois qu'ils ont faillé. Vous devez disposer de l'ancien et en recréer un nouveau.

Vous devez également vous assurer de fermer correctement le proxy du service client. Il est possible qu'un proxy de service WCF lève une exception à la fermeture, et si cela se produit, la connexion n'est pas fermée, vous devez donc abandonner. Utilisez le modèle "try {Close}/catch {Abort}". Gardez également à l'esprit que la méthode dispose call close (et donc peut jeter une exception de la disposition), de sorte que vous ne pouvez pas utiliser une utilisation comme avec des classes jetables normales.

Par exemple:

try 
{ 
    if (yourServiceProxy != null) 
    { 
     if (yourServiceProxy.State != CommunicationState.Faulted) 
     { 
      yourServiceProxy.Close(); 
     } 
     else 
     { 
      yourServiceProxy.Abort(); 
     } 
    } 
} 
catch (CommunicationException) 
{ 
    // Communication exceptions are normal when 
    // closing the connection. 
    yourServiceProxy.Abort(); 
} 
catch (TimeoutException) 
{ 
    // Timeout exceptions are normal when closing 
    // the connection. 
    yourServiceProxy.Abort(); 
} 
catch (Exception) 
{ 
    // Any other exception and you should 
    // abort the connection and rethrow to 
    // allow the exception to bubble upwards. 
    yourServiceProxy.Abort(); 
    throw; 
} 
finally 
{ 
    // This is just to stop you from trying to 
    // close it again (with the null check at the start). 
    // This may not be necessary depending on 
    // your architecture. 
    yourServiceProxy = null; 
} 

Il y a un article de blog sur ce here

+0

10 si je pouvais - wow, ce comportement est tout à fait sous le radar, n'aurait élaboré ce qui se passait si je n'avais pas trébuché sur cette réponse. –

+0

Bravo! J'ai implémenté une version de ceci comme une méthode d'extension: TryDispose sur la classe de proxy pour l'usage par d'autres. –

+0

@ Moby's Stunt Double - êtes-vous capable de partager votre code? – RichardHowells

Questions connexes