What? I must be kidding. This is not blog for kids trying to play with .NET. Every professional .NET developer knows how to consume WCF. Don’t they? There is nothing more easier than that.

Well, not that long ago I realized that the way I like to consume WCF services is not 100% correct.

What I like to do is use of “using”:

using (var client = new SomeServiceClient())
{
  var response = client.SomeServiceOperation(request);
  //return or do something
}

While this looks nice, here is thing which even kids won’t like: Dispose method for the client is not really implemented correctly by Microsoft! It could throw an exception if there is network problem therefore masking other exceptions that could have happened in between. You can understand the issue better if you have a look at WCF samples (WF_WCF_SamplesWCFBasicClientUsingUsing).

MS proposes their own solution (read it here):

var client = new SomeServiceClient();
try
{
    var response = client.SomeServiceOperation(request);
    // do something
    client.Close();
}
catch (Exception)
{
    client.Abort();
    throw;
}

While this is correct way it is too much code, especially if you put catch blocks for Communication and Timeout exceptions as recommended by MS. Guys over internet propose other solutions, like wrapping the call or extension methods.

Here is my solution, which is nothing new, but just slightly modified version of best proposed answer on SO:

Elegant example of usage with return statements:

return Service<ISomeServiceChannel>.Use(client =>
{
    return client.SomeServiceOperation(request);
});

And the solution itself:

public static class Service<TChannel>
{
    public static ChannelFactory<TChannel> ChannelFactory = new ChannelFactory<TChannel>("*");

    public static TReturn Use<TReturn>(Func<TChannel, TReturn> codeBlock)
    {
        var proxy = (IClientChannel)ChannelFactory.CreateChannel();
        var success = false;
        try
        {
            var result = codeBlock((TChannel)proxy);
            proxy.Close();
            success = true;
            return result;
        }
        finally
        {
            if (!success)
            {
                proxy.Abort();
            }
        }
    }
}

And some bitterness for the end. It doesn’t look like Microsoft is in a hurry to fix Dispose while they should accordingly to their own guidelines. But even knowing this I still like “using” and will probably be stick to it for smaller things. You see, my problem is that I have never-ever experienced inconveniences or issues because of this.

Is it same for you or do you have a story to share with me/others in your comment? :)

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInEmail this to someone