WCF Client and the “using” Statement

As I was researching patterns and practices for a WCF client implementation, I came across a bug in the .Net implementation of ClientBase (whether it’s actually a bug is arguable). It’s well documented on the web, but it could cause major headaches if you happened to miss it.

The core of the issue is that ClientBase implements IDisposable. With this knowledge, just about any programmer would naturally wrap its usage in a using{} block. Digging deeper, you’ll find that the ClientBase Dispose() method simply calls Close() on the underlying connection. This is problematic because in certain connection states (such as “Faulted”), the Close() will fail. As I said, this is well documented elsewhere, for example: on MSDN, Stack Overflow, and here.

There are a few different solutions to this issue. I went with a simple Disposable wrapper…

// Get a disposable MyClientWrapper object
using(var clientWrapper = ClientFactory.GetMyClientWrapper())
{
    clientWrapper.Client.DoSomething();
}

public class MyClientWrapper : IDisposable
{
    private readonly MyClient _client;

    public MyClientWrapper(Binding binding, Uri endpoint)
    {
        // creates an instance of MyClient, which is derived from ClientBase<T>
        _client = new MyClient(binding, new EndpointAddress(endpoint.ToString()));
    }

    public MyClient Client
    {
        get { return _client; }
    }

    public void Dispose()
    {
        // safe dispose with extension method (below)
        _client.CloseProxy();
    }
}

// extension method for safe Close() on ClientBase<T>
public static void CloseProxy(this ClientBase<T> proxy) where T : class
{
    try
    {
        if (proxy.State != CommunicationState.Closed 
                && proxy.State != CommunicationState.Faulted)
        {
            proxy.Close(); // may throw exception while closing
        }
        else
        {
            proxy.Abort();
        }
    }
    catch (CommunicationException)
    {
        proxy.Abort();
        throw;
    }
}