2009-12-24 5 views
1

J'ai créé un service singleton WCF avec netNamedPipeBinding. Lorsqu'une exception de canal se produit, elle laisse un canal dans un état défectueux et toutes les opérations suivantes émettent des exceptions. Comment puis-je empêcher cela? Je veux qu'une exception TimeoutException, ou l'une des autres exceptions communes, pour faire échouer une seule opération, et ne pas rendre le service ne répond pas.Comment éviter qu'une exception de canal ne fasse fonctionner un service WCF?

+0

Êtes-vous sûr que c'est le canal de service qui ne répond plus en cas d'erreur? J'utilise les services de Singleton tout le temps sur un très grand site, et je n'ai jamais eu le problème que vous décrivez. – nitzmahone

+0

J'ai eu des journaux qui dit que le canal est inutilisable parce qu'il est dans un état défectueux –

Répondre

2

Il existe un autre moyen. Vous pouvez instancier le proxy client pour chaque requête au lieu d'utiliser une instance unique pour plusieurs requêtes. De cette façon, si le canal entre dans un état défectueux, il est rejeté de toute façon.

Ceci est un peu difficile car vous ne devriez pas disposer un canal, en plus d'être IDisposable.

Il ne fonctionnera pas:

using(var channel = channelFactory.CreateChannel()) 
{ 
    return channel.ServiceMethod(parameter); 
} 

Au lieu de cela, vous devez:

public static class Service<T> 
{ 
    public static ChannelFactory<T> _channelFactory = new ChannelFactory<T>(""); 

    public static TResult Use<TResult>(Func<T, TResult> func) 
    { 
     TResult output; 
     var channel = (IClientChannel)_channelFactory.CreateChannel(); 
     bool success = false; 
     try 
     { 
      output = func((T)proxy); 
      channel.Close(); 
      success = true; 
     } 
     finally 
     { 
      if (!success) 
      { 
       proxy.Abort(); 
      } 
     } 
     return output; 
    } 
} 

return Service<IService>.Use(channel => 
{ 
    return channel.ServiceMethod(parameter); 
}); 
8

Vous devez placer vos exceptions du côté serveur dans FaultException. Si vous contrôlez les deux extrémités du fil, et que les deux extrémités sont .NET, vous pouvez simplement envelopper une exception .NET dans un FaultException<T> et l'envoyer au client. De cette façon, le canal reste utilisable.

Voir Specifying and Handling Faults in Contracts and Services sur MSDN pour plus d'informations, plus vérifier ce article on CodeProject et ce blog Why Use WCF FaultException sur le même sujet.

En outre, pour vous faciliter la vie, consultez le IErrorHandler interface que vous pouvez implémenter côté serveur pour récupérer globalement les exceptions et les convertir en erreurs. Voir aussi beaucoup de billets de blog sur le sujet, c'est-à-dire IErrorHandler: a generic Fault Converter ou beaucoup d'autres (Bing ou Google pour en savoir plus).

Pour rendre votre vie encore plus facile, vous pouvez mettre en œuvre le IErrorHandler comme un comportement, que vous pouvez activer ou désactiver votre service - soit dans la configuration de service, ou en définissant un attribut de votre classe de service. Il y a pas mal d'implémentation flottant sur internet, celle que j'aime est ici: Useful WCF Behavior: IErrorHandler.

+0

a également trouvé une autre solution, s'il vous plaît voir ma réponse –

+0

Je me demande quels sont les avantages de votre solution sur la mienne. –

+0

Il est intéressant de noter que mes services ont cessé de fonctionner lorsque j'ai implémenté ma solution. J'ai donc dû implémenter le vôtre pour les ramener à la normale. –