So a using statement automatically calls the dispose method on the object that is being \"used\", when the using block is exited, right?
But when is this necessary/benef
The using construct enforces deterministic disposal -- i.e. release of resources. In your example above, yes, if you don't employ a "using" statement, the object will be disposed, but only if the recommended disposable pattern (that is, disposing of resources from a class finalizer, if applicable) has been implemented for the class in question (in your example, the Font class). It should be noted, that the using construct can only be used with objects that implement the IDisposable
interface. It is the presence of that interface on an object that allows using to "call" the Dispose
method.
Additionally, underlying resources will only be released when the garbage collector decides to collect your out-of-scope Font object. A key concept in .Net programming (and most languages with a garbage collector) is that just because an object goes out of scope does not mean that it is finalized/released/destroyed, etc. Rather, the garbage collector will perform the clean-up at a time it determines -- not immediately when the object goes out of scope.
Finally, the using statement "bakes in" a try/finally construct to ensure that Dispose is called regardless of contained code throwing an exception.
When the method exits, wont the Font object be disposed of anyway?
No, it will become unreferenced, and thus eligible for garbage collection. Unless something else (e.g. a reference held in another data structure) holds on to a reference.
Or does the Dispose method get run at another time after the method exits?
Yes, in a process not allocating much memory that could be a considerable time after the method has exited.
Garbage Collection is inherently asynchronous and lazy, thus making it a great way to ensure memory is freed, if memory is not too limited; but poor for almost any other resource.
Without using
(or manually calling Dispose()
), the object will eventually be disposed of, just not at a deterministic time. That is, it can happen straight away, in two days' time, or (in some cases) never.
For things like, say, network connections, you want the connection to close when you're done with it, not "whenever", otherwise it'll idle around hogging up a socket.
Further, for things like mutex locks, you do not want those to be released "whenever", or else deadlock is likely to result.
The 'using' statement is most useful when working with unmanaged objects, like database connections.
In this way, the connection is closed and disposed no matter what happens in the code block.
For more discussion, see this article on CodeProject: http://www.codeproject.com/KB/cs/tinguusingstatement.aspx
They are useful in any situation when you want cleanup code to be called on an object deterministically and regardless of exceptions (since a using
statement is really just a try/finally
).
Most often they are used to clean up unmanaged resources but you can use them however you see fit.
Here's what using really does (based on your example)
Font font1 = new Font(...);
try
{
// code that uses font...
}
finally
{
if (font1 != null)
font1.Dispose();
}
So you don't need to worry about exception making your variable not disposed.