Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems with the Using Statement and WCF client

I've been wrapping all the code that invoke WCF calls within an using statement in a thought that the object will be disposed properly. When I'm googling for an exception "Http service located at .. is too busy" I found this link http://msdn.microsoft.com/en-us/library/aa355056.aspx that says should not use using statement in typed proxies. Is that really true? I think I got a big code change (sigh). Is this problem comes only in typed proxies?

Sample code:

private ServiceClient proxy;

using(proxy = new ServiceClient("ConfigName", "http://serviceaddress//service.svc")){
    string result = proxy.Method();
}
like image 783
VJAI Avatar asked Jul 18 '11 07:07

VJAI


3 Answers

The core of the problem is: at the end of your using block (which generally is a very good idea to have!), the WCF proxy will be disposed. However, during disposing of the WCF proxy, exceptions can occur - and those will cause the app to misbehave. Since this is done implicitly at the end of the using block, you might not even really see where the error occurs.

So typically, Microsoft recommends a pattern something like this:

private ServiceClient proxy;

try
{
    proxy = new ServiceClient("ConfigName", "http://serviceaddress//service.svc");
    string result = proxy.Method();
    proxy.Close();    
}
catch (CommunicationException e)
{
   // possibly log error, possibly clean up
   proxy.Abort();
}
catch (TimeoutException e)
{
   // possibly log error, possibly clean up
   proxy.Abort();
}
catch (Exception e)
{
   // possibly log error, possibly clean up
   proxy.Abort();
   throw;
}

You need to call the proxy.Close() method explicitly and be prepared to handle any exceptions that might occur from that call, too.

like image 86
marc_s Avatar answered Nov 05 '22 15:11

marc_s


Wrap the proxy operation and instantiation calls up in a class implementing IDisposable. When disposing, check the state property of the proxy and tidy up the channel before closing.

public void Dispose()
{
    if (this.MyProxy != null && this.MyProxy.State == CommunicationState.Faulted)
    {
        this.MyProxy.Abort();
        this.MyProxy.Close();
        this.MyProxy = null;
    }
    // ...more tidyup conditions here
} 
like image 24
HoganNZ Avatar answered Nov 05 '22 13:11

HoganNZ


I like the approach from the comment from "Eric" on this blog (which is similar to another article: http://redcango.blogspot.com/2009/11/using-using-statement-with-wcf-proxy.htm):

"Personally, I like to create my own partial class for the client and override the Dispose() method. This allows me to use the ‘using’ block as I normally would.

public partial class SomeWCFServiceClient : IDisposable
{
  void IDisposable.Dispose()
  {
   if (this.State == CommunicationState.Faulted)
   {
    this.Abort();
   }
   else
   {
     this.Close();
   }
  }
}
like image 40
AlignedDev Avatar answered Nov 05 '22 14:11

AlignedDev