Just sharing some of my inconsequential lunch conversations with you... RSS  

Tuesday, September 30, 2008

WCF refusing connections after 10 requests

Today I learned the hard way the problem of assuming behavior. I assumed IDisposable would clean up the session, but I was wrong.

It seems like we still have to invoke Close explicitly. The documentation clearly recommends the following pattern:

try
{
...
client.Close();
}
catch (CommunicationException e)
{
...
client.Abort();
}
catch (TimeoutException e)
{
...
client.Abort();
}
catch (Exception e)
{
...
client.Abort();
throw;
}



I wasn't closing the client proxy, so I was reaching the default WCF 10 concurrent calls limit. The funny thing is that the integration tests were working fine, but not the corresponding ASP.NET usage. Why? Here's a possible explanation:




Hopefully, you were clued in enough to know you need to dispose these objects... but the problem is that (...) the (...) code blocks will cause major problems in a production environment. The choice the WCF developers made here is questionable at best and goes against everything you thought you knew about the IDisposable interface. Everywhere else in the .NET framework, you can count on Dispose cleaning up your object... not so in this case. The problem is that Dispose actually calls Close, and if you are using something like the WsHttpBinding, Close doesn't just clean up resources managed by the object. Close actually needs to make a call to the server and tell the server to clean up your session before it shuts down. When that call back to the server can't be made for any reason--which can happen quite often--Close fires an exception and the object is not disposed. There is another method, Abort, which you need to call to clean up the object's state.

No comments:

Development Catharsis :: Copyright 2006 Mário Romano