0

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>(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?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Gil
  • 109
  • 1
  • 10
  • You don't have to call `.Close()` after each call to your WCF service - as long as there's no error, you're quite OK to use that proxy again for another call. The point about this best practice is that you shouldn't put your WCF proxy calls into a `using(....) { .... }` block since that block will dispose the proxy at the closing `}` and closing the WCF proxy might cause an exception which would go unnoticed with the using block. – marc_s Jul 31 '11 at 08:21
  • Possible duplicate of [What is the best workaround for the WCF client \`using\` block issue?](http://stackoverflow.com/questions/573872/what-is-the-best-workaround-for-the-wcf-client-using-block-issue) – Drew Noakes Oct 15 '15 at 14:43

2 Answers2

0

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.

Emond
  • 50,210
  • 11
  • 84
  • 115
0

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.

Manfred
  • 5,320
  • 3
  • 35
  • 29