What is the best workaround for the WCF client `using` block issue?

c#, using, vb.net, wcf, wcf-client

Solution

Actually, although I blogged (see Luke's answer), I think this is better than my IDisposable wrapper. Typical code:

Service<IOrderService>.Use(orderService=>
{
  orderService.PlaceOrder(request);
}); 

(edit per comments)

Since `Use` returns void, the easiest way to handle return values is via a captured variable:

int newOrderId = 0; // need a value for definite assignment
Service<IOrderService>.Use(orderService=>
  {
    newOrderId = orderService.PlaceOrder(request);
  });
Console.WriteLine(newOrderId); // should be updated

Problem

I like instantiating my WCF service clients within a `using` block as it's pretty much the standard way to use resources that implement `IDisposable`: ``` using (var client = new SomeWCFServiceClient()) { //Do something with the client } ``` But, as noted in this MSDN article, wrapping a WCF client in a `using` block could mask any errors that result in the client being left in a faulted state (like a timeout or communication problem). Long story short, when `Dispose()` is called, the client's `Close()` method fires, but throws an error because it's in a faulted state. The original exception is then masked by the second exception. Not good. The suggested workaround in the MSDN article is to completely avoid using a `using` block, and to instead instantiate your clients and use them something like this: ``` try { ... client.Close(); } catch (CommunicationException e) { ... client.Abort(); } catch (TimeoutException e) { ... client.Abort(); } catch (Exception e) { ... client.Abort(); throw; } ``` Compared to the `using` block, I think that's ugly. And a lot of code to write each time you need a client. Luckily, I found a few other workarounds, such as this one on the (now defunct) IServiceOriented blog. You start with: ``` public delegate void UseServiceDelegate<T>(T proxy); public static class Service<T> { public static ChannelFactory<T> _channelFactory = new ChannelFactory<T>(""); public static void Use(UseServiceDelegate<T> codeBlock) { IClientChannel proxy = (IClientChannel)_channelFactory.CreateChannel(); bool success = false; try { codeBlock((T)proxy); proxy.Close(); success = true; } finally { if (!success) { proxy.Abort(); } } } } ``` Which then allows: ``` Service<IOrderService>.Use(orderService => { orderService.PlaceOrder(request); }); ``` That's not bad, but I don't think it's as expressive and easily understandable as the `using` block. The workaround I'm currently trying to use I first read about on blog.davidbarret.net. Basically, you override the client's `Dispose()` method wherever you use it. Something like: ``` public partial class SomeWCFServiceClient : IDisposable { void IDisposable.Dispose() { if (this.State == CommunicationState.Faulted) { this.Abort(); } else { this.Close(); } } } ``` This appears to be able to allow the `using` block again without the danger of masking a faulted state exception. So, are there any other gotchas I have to look out for using these workarounds? Has anybody come up with anything better?

Original source

Related problems