tags:

views:

1596

answers:

4

Hi,

I'd like to know when i should and shouldn't be wrapping things in a USING block.

From what I understand, the compiler translates it into a try/finally, where the finally calls Dispose() on the object.

I always use a USING around database connections and file access, but its more out of habit rather than a 100% understanding. I know you should explicity (or with a using) Dispose() objects which control resources, to ensure they are released instantly rather than whenever the CLR feels like it, but thats where my understanding breaks down.

Are IDisposables not disposed of when they go out of scope?

Do I only need to use a USING when my object makes use of Dispose to tidy itself up?

Thanks

Edit: I know there are a couple of other posts on the USING keyword, but I'm more interested in answers relating the the CLR and exactly whats going on internally

Andrew

+11  A: 

No, IDisposable items are not disposed when they go out of scope. It is for precisely this reason that we need IDisposable - for deterministic cleanup.

They will eventually get garbage collected, and if there is a finalizer it will (maybe) be called - but that could be a long time in the future (not good for connection pools etc). Garbage collection is dependent on memory pressure - if nothing wants extra memory, there is no need to run a GC cycle.

Interestingly (perhaps) there are some cases where "using" is a pain - when the offending class throws an exception on Dispose() sometimes. WCF is an offender of this. I have discussed this topic (with a simple workaround) here.

Basically - if the class implements IDisposable, and you own an instance (i.e. you created it or whatever), it is your job to ensure that it gets disposed. That might mean via "using", or it might mean passing it to another piece of code that assumes responsibility.

I've actually seen debug code of the type:

#if DEBUG
    ~Foo() {
        // complain loudly that smoebody forgot to dispose...
    }
#endif

(where the Dispose calls GC.SuppressFinalize)

Marc Gravell
And if you do use this technique, please, please, please don't forget the '#if DEBUG'. That's you I'm thinking of JetBrains, with your 30000 objects on the finalizer queue of Visual Studio...
Will Dean
Oh, that's unfortunate.
Robert Rossney
+3  A: 

"Are IDisposables not disposed of when they go out of scope?"

No. If the IDisposable object is finalizable, which is not the same thing, then it will be finalized when it's garbage collected.

Which might be soon or might be almost never.

Jeff Richter's C#/CLR book is very good on all this stuff, and the Framework Design Guidelines book is also useful.

Do I only need to use a USING when my object makes use of Dispose to tidy itself up?

You can only use 'using' when the object implements IDisposable. The compiler will object if you try to do otherwise.

Will Dean
A: 

Thanks, thats all i needed to know :)

Andrew Bullock
A: 

To add to the other answers, you should use using (or an explicit Dispose) whenever an object holds any resources other than managed memory. Examples would be things like files, sockets, database connections, or even GDI drawing handles.

The garbage collector would eventually finalise these objects, but only at some unspecified time in the future. You can't rely on it happening in a timely fashion, and you might have run out of that resource in the meantime.

wilberforce
Arguably, you should simply be using "using" whenever the class implements IDisposable. What it does is an implementation detail ;-p It is a *finalizer* that you should only add if your class is wrapping an unmanaged resource. There are examples of IDisposable in purely managed code...
Marc Gravell
Nice comment, should have made it an answer for some vote love xx
Andrew Bullock
Marc: you're right. I guess I was really trying to explain the motivation for why the implementer might have made a class IDisposable, rather than garbage collection solving all resource management problems.
wilberforce