Click here to Skip to main content
15,891,951 members
Articles / WCF

Don't Use 'using()' with a WCF Proxy

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
21 Jan 2016CPOL 5.1K   1   1
Don't use 'using()' with a WCF proxy

If you're trying to be a conscientious developer and making sure that you cleanup your resources - great! You are writing 'using()' blocks around all of your disposable items - great... except when the disposable item is a WCF Client/Proxy! The using() statement and the try/finally effectively have the same IL:

MSIL
// The IL for this block is effectively the same as
            // the IL for the second block below
            using (var win = new Form())
{
}

            // This is the second block
            Form f = null;
            try
{
    f = new Form();
}
            finally
{
            if (f != null)
    {
        f.Dispose();
    }
}

Here's the IL for the 'using()' block above compiled in Release mode:

MSIL
IL_0000:  newobj     instance void [System.Windows.Forms]System.Windows.Forms.Form::.ctor()
IL_0005:  stloc.0
.try
{
    IL_0006:  leave.s    IL_0012
}  // end .try
finally
{
    IL_0008:  ldloc.0
    IL_0009:  brfalse.s  IL_0011
    IL_000b:  ldloc.0
    IL_000c:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()
    IL_0011:  endfinally
}  // end handler

Here's the IL for the second block (try/finally) compiled in Release mode:

MSIL
IL_0012:  ldnull
IL_0013:  stloc.1
.try
{
    IL_0014:  newobj     instance void [System.Windows.Forms]System.Windows.Forms.Form::.ctor()
    IL_0019:  stloc.1
    IL_001a:  leave.s    IL_0026
}  // end .try
finally
{
    IL_001c:  ldloc.1
    IL_001d:  brfalse.s  IL_0025
    IL_001f:  ldloc.1
    IL_0020:  callvirt   instance void [System]System.ComponentModel.Component::Dispose()
    IL_0025:  endfinally
}  // end handler

As you can see, the IL is nearly identical.

Well, this is all fine and good but let's get back to the issue with WCF. The problem is that if an exception is thrown during disposal of the WCF client/proxy, the channel is never closed. Now, in general, any exception that occurs during disposal of an object is indeed undesirable. But, in the case of WCF, multiple channels remaining open could easily cause your entire service to fall on its face - not to mention what might eventually happen to your web server.

Here is an alternative solution that can be used:

C#
WCFProxy variableName = null;
            try
{
    variableName = new WCFProxy();

            // TODO code here

    variableName.Close();
}
            // if you need to catch other exceptions, do so here...
            catch (Exception)
{
            if (variableName != null)
    {
        variableName.Abort();
    }
            throw;
}

MSDN does have a brief on this issue which you can read here.

This article was originally posted at http://dave-black.blogspot.com

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Black Box Solutions, Inc.
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
PraiseVery good Pin
mrrobot2322-Jan-16 8:21
mrrobot2322-Jan-16 8:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.