2011-07-31 6 views
0

je lis que les meilleures pratiques pour l'utilisation de proxy WCF serait:WCF fermer les meilleures pratiques

YourClientProxy clientProxy = new YourClientProxy(); 

try 
{ 
    .. use your service 
    clientProxy.Close(); 
} 
catch(FaultException) 
{ 
    clientProxy.Abort(); 
} 
catch(CommunicationException) 
{ 
    clientProxy.Abort(); 
} 
catch (TimeoutException) 
{ 
    clientProxy.Abort(); 
} 

Mon problème est, après que je répartisse mes proxy, j'attribue des gestionnaires d'événements à et initialiser également une autre méthode en utilisant la proxy:

public void InitProxy() 
{ 
    sdksvc = new SdkServiceClient(); 
    sdksvc.InitClusteringObjectCompleted += new EventHandler<InitClusteringObjectCompletedEventArgs>(sdksvc_InitClusteringObjectCompleted); 
    sdksvc.InitClusteringObjectAsync(Utils.DSN, Utils.USER,Utils.PASSWORD); 
    sdksvc.DoClusteringCompleted += new EventHandler<DoClusteringCompletedEventArgs>(sdksvc_DoClusteringCompleted); 
    sdksvc.CreateTablesCompleted += new EventHandler<CreateTablesCompletedEventArgs>(sdksvc_CreateTablesCompleted); 
} 

Je dois maintenant appeler la méthode InitProxy() chaque fois que j'utilise le proxy si je veux l'utiliser comme la meilleure pratique suggère.

Des idées pour éviter cela?

+0

Vous n'avez pas besoin d'appeler '.Close()' après chaque appel à votre service WCF - tant qu'il n'y a pas d'erreur, vous pouvez tout à fait utiliser ce proxy pour un autre appel. Le point à propos de cette meilleure pratique est que vous ne devriez pas mettre vos appels proxy WCF dans un bloc using (....) {....} 'puisque ce bloc disposera le proxy à la fermeture'} 'et fermera le proxy WCF peut provoquer une exception qui passerait inaperçue avec le bloc using. –

+0

Copie possible de [Quelle est la meilleure solution de contournement pour le client WCF \ 'en utilisant \' problème de bloc?] (Http://stackoverflow.com/questions/573872/what-is-the-best-workaround-for-the- wcf-client-using-block-issue) –

Répondre

0

Il existe plusieurs options. Une option est d'écrire une classe d'aide comme suit:

public class SvcClient : IDisposable { 
    public SvcClient(ICommunicationObject service) { 
     if(service == null) { 
     throw ArgumentNullException("service"); 
     } 
     _service = service; 
     // Add your event handlers here, e.g. using your example: 
     sdksvc = new SdkServiceClient(); 
     sdksvc.InitClusteringObjectCompleted += new EventHandler<InitClusteringObjectCompletedEventArgs>(sdksvc_InitClusteringObjectCompleted); 
     sdksvc.InitClusteringObjectAsync(Utils.DSN, Utils.USER,Utils.PASSWORD); 
     sdksvc.DoClusteringCompleted += new EventHandler<DoClusteringCompletedEventArgs>(sdksvc_DoClusteringCompleted); 
     sdksvc.CreateTablesCompleted += new EventHandler<CreateTablesCompletedEventArgs>(sdksvc_CreateTablesCompleted); 
    } 
    public void Dispose() { 
     try { 
     if(_service.State == CommunicationState.Faulted) { 
      _service.Abort(); 
     } 
     } 
     finally { 
     _service.Close(); 
     } 
    } 
    private readonly ICommunicationObject _service; 
} 

Pour utiliser cette classe écrire:

var clientProxy = new YourClientProxy(); 
using(new SvcClient(clientProxy)) { 
    // use clientProxy as usual. No need to call Abort() and/or Close() here. 
} 

Lorsque le constructeur de SvcClient est appelé établit alors l'instance SdkServiceClient comme vous le souhaitez. En outre, la classe SvcClient nettoie le proxy du client de service en interrompant et/ou en fermant la connexion, quelle que soit la manière dont le flux de contrôle quitte le bloc using.

0

Je ne vois pas comment le ClientProxy et l'InitProxy() sont liés mais s'ils sont liés, je déplacerais l'initialisation de ClientProxy vers InitProxy (ou créer une méthode qui initialise les deux) pour que vous puissiez contrôler à la fois leur durée de vie à partir de là.