views:

20

answers:

1

In a pre-WCF .NET (C#) web service, I have an expensive IDisposable resource that I'm holding a static (actually ThreadStatic) reference to. (Internally it holds a SqlConnection.) How can I insure that this is disposed when the app pool refreshes, should I simply suppress the FxCop warning and not worry about it, or is there a third option?

Originally the service opened the connection on each request with a using block, but that design was rejected due to a "connection resource issue."

+1  A: 

This design will be rejected due to a connection resource issue. If you had problems before, you'll have them again, since you will now be using more SqlServer connections (if it's thread static, then each thread will have one SqlServer and - more importantly - one underlying real connection, even when it's not using the connection and would have returned the underlying connection to the pool).

Jon Hanna
Very good point. I didn't choose the new design. What would you suggest?
TrueWill
You need to re-examine your connection resource issue, and see what the actual problem was. As a rule the best pattern is to open a connection, perform the operation, and then close it, either by a using block on the connection or - if you are returning a datareader so it can be iterated through efficiently, a datareader in a using block created with the CloseConnection option so it's disposal trigger's the connection's disposal. This way the "real" connection is returned to the pool ASAP. Your change here is making matters worse by never returning it. Where did the usual pattern go wrong?...
Jon Hanna
... could it be that errors happened between creating a connection for a datareader (and hence not in a using) and putting the datareader into the using? Such a situation can cause leaks (I use a wrapper class for this that will dispose the connection on its disposal, but when it successfully creates a datareader with the closing option, will "stop owning" the connection, as it's now the reader that will close it. Another source of errors is if you do the `using` on the datareader in an interator block and, whether as an error or deliberately, never enter the using block because the first ...
Jon Hanna
... iteration doesn't happen. Again, one solution is a wrapper class, in this case an enumerable wrapper that "peeks" at the first item so that the using block in the reader-using code is always entered. Other causes are of course possible, the above are just causes I've seen in real code. The one thing I'm sure of is that the solution to using too many simultaneous connections is not to change to a design that uses more connections.
Jon Hanna