开发者

WCF closing best practice

I read that the best practice for using WCF proxy would be:

YourClientProxy clientProxy = new YourClientProxy();

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

My problem is, after I allocate my proxy, I assign event handlers to it and also initialize other method using the proxy:

public void InitProxy()
{
    sdksvc = new SdkServiceClient();
    sdksvc.InitClusteringObjectCompleted += new EventHandler<InitClusteringObjectCompletedEventArgs&g开发者_运维问答t;(sdksvc_InitClusteringObjectCompleted);
    sdksvc.InitClusteringObjectAsync(Utils.DSN, Utils.USER,Utils.PASSWORD);
    sdksvc.DoClusteringCompleted += new EventHandler<DoClusteringCompletedEventArgs>(sdksvc_DoClusteringCompleted);
    sdksvc.CreateTablesCompleted += new EventHandler<CreateTablesCompletedEventArgs>(sdksvc_CreateTablesCompleted);
}

I now need to call the InitProxy() method each Time I use the proxy if I want to use it as best practice suggests.

Any ideas on how to avoid this?


There are several options. One option is to write a helper class as follows:

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

To use this class write the following:

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

When the constructor for SvcClient is called it then sets up the SdkServiceClient instance as desired. Furthermore the SvcClient class cleans up the service client proxy as well aborting and/or closing the connection as needed regardless of how the control flow leaves the using-block.


I don't see how the ClientProxy and the InitProxy() are linked but if they are linked this strong I'd move the initialization of the ClientProxy to the InitProxy (or make a method that initializes both) so you can control both their lifespans from there.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜