Friday, March 13, 2009

WCF auto generated client proxy classes - instantiation gotcha

WCF auto-generated client proxy classes all implement IDisposable. This makes them candidates for instantiating via using statements i.e.:

using (MyServiceBindingClient client = new MyServiceBindingClient())

This approach should not be taken when working with WCF client proxy classes. This is because if an exception is thrown within the try block above, you will never get to see the true exception:

The problem is that if the client.Open() call (or any subsequent calls placed on the client) throws an exception, we end up leaving the using block, which causes our client’s IDisposable interface to get fired. The Dispose routine on WCF classes have a bad tendency to then fire another exception at that point, because we are attempting to perform a close() operation on the client but it has already faulted. And so the exception that eventually gets caught by any surrounding try/catch block will be the exception thrown by calling close() on a faulted client. It will not be the original exception, and the original exception is not accessable via the InnerException property.

Microsoft’s recommended way of avoiding this situation is to not instantiate WCF clients via using statements. I.e. instantiate/use them as per non-IDisposable’s, and make sure you have appropriate exception handling and explicit calls to dispose your IDisposable.