Does the “using” keyword mean the object is dispos

2020-02-26 14:31发布

问题:

I struck up a conversation with my colleague today, who said she'd just learned the reason behind using the using statement.

 //Using keyword is used to clean up resources that require disposal (IDisposable interface). 

 using (StreamReader reader = new StreamReader(@"C:\test.txt")) 
 { 
 string line = reader.ReadLine(); 
 } 

I pointed out that the object is marked as "Can be disposed" but not actually disposed and garbage-collected unless GC decides to do so.

She responded that the object will be disposed automatically once that using statement ends because the using statement is translated to try-catch-finally block. So, the object must get disposed at the very end of the using statement.

I was confused by this, because I know that using a using statement does not guarantee that the object gets GC-collected. All that happens is that the Dispose() method would be called. The GC decides when to GC it regardless. But when she asked for proof, I could not find any.

Does anyone know how this works, and how to prove it?

回答1:

You're talking about two very different things.

The object will be disposed as soon as the using-block ends. That doesn't say anything about when it is garbage collected. The only time heap memory is released is when a garbage collection occurs - which only happens under memory pressure (unless you use GC.Collect explicitly).

Disposing an object simply means calling its Dispose method. That most often means releasing either a scarce resource, or a native resource (in practice, all scarce resources are native - sockets, files, ...). Now, it's handy that the lifetime of the disposable object in your case is limited in scope, so it could theoretically be collected as soon as the using-block ends - however, that doesn't really happen in practice, since the .NET runtime tries to avoid collections - they're expensive. So until you cross a memory allocation threshold, no collection is going to happen, even though you have a dead object on the heap.

So what's the point of Dispose? Nothing to do with managed memory. You don't really care about managed memory, and you shouldn't expect that Dispose will actually be called - it doesn't have to be. The only thing that has to be called by the runtime is the finalizer, and you can only ever use that for disposing of native resources - in fact, there's no guarantee if the objects you have a reference to still exist by the time the finalizer runs - the managed memory might have already been reclaimed by then. That's why you never handle managed resources in a finalizer.

So yes, she was completely right. The point is that IDisposable has nothing to do with the garbage collector. Disposed does not mean garbage collected.



回答2:

She is right on the money using statement is just a syntatic sugar for try/finally{obj.Dispose();} . using statement ensures that the object will be disposed.(Dispose method will be called) but it has no relationship with garbage collection.

Take a look at this Understanding-the-using-statement

Short answer: So now we know using statement is just calling Dispose and does nothing other than that, and keep in mind that Dispose method is no special than any other methods. It is just a method and that's it. So it is no way related to garbage collection. Interestingly "Garbage Collector" doesn't even know about Dispose method or IDisposable.

Hope this helps