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

2 thoughts on “WCF Client and the “using” Statement”

  1. Kevin,
    Great catch! I would extend this a little. According to MS best practices a Dispose method should not throw an exception. I would put a try/catch (with some logging) around the _client.CloseProxy() call. A resource at work to ask about WCF is Doug E. He can go on at great length about WCF and handling of the proxy šŸ™‚

  2. Hello blogger, i must say you have high quality posts here.
    Your blog should go viral. You need initial traffic only.

    How to get it? Search for: Mertiso’s tips go viral

Leave a Reply

Your email address will not be published. Required fields are marked *

*