I am developing some utilities to control threading for a game server and am experimenting with using an IDisposable "token" so that I can use code like this:
using(SyncToken playerListLock = Area.ReadPlayerList())
{
//some stuff with the player list here
}
The idea being that I acquire a read lock on the list of players in an area and it is automatically unlocked when it goes out of scope with the using block. So far this is all implemented and working, but I am worried about the timing of the call to Dispose().
Does the SyncLock variable simply get marked for disposal when the program leaves the using block and then get cleaned up by the Garbage Collector at some point later, or does the current thread execute the Dispose() method as a part of leaving the using block?
This pattern is basically RAII, where a lock is the resource being allocated. An example of this pattern (ie, using an IDisposable "token") has also been used by Jon Skeet in his MiscUtils here
It's cleaned up immediately after the using scope exits.
In effect, this
using(SyncToken playerListLock = Area.ReadPlayerList())
{
//some stuff with the player list here
}
is syntactic sugar for
IDisposable playerListLock;
try {
playerListLock = Area.ReadPlayerList();
}
finally {
if (playerListLock != null) playerListLock.Dispose();
}
The very purpose of using is to enable RAII-like functionality in C#, which doesn't feature deterministic destruction.
Dispose gets called when you exit the scope of the using. Syntactic sugar for:
MyObj instance = null;
try
{
instance = new MyObj();
}
finally
{
instance.Dispose();
}
Dispose() is called immediataly when the using block is exited.
using is more or less the C# equivalent of the RAII idiom in C++.
The using docs state that:
The using statement ensures that
Dispose is called even if an exception
occurs while you are calling methods
on the object. You can achieve the
same result by putting the object
inside a try block and then calling
Dispose in a finally block; in fact,
this is how the using statement is
translated by the compiler.
So yes, it is called as soon as you exit the block.
Dispose gets called at the end of the using block, you should implementation Dispose for SyncToken so that the SyncLock can be released deterministically, this is whole point of the Dispose Pattern.
When you leave the scope of the using block the Dispose() function is called releasing the allocated resource, however the SyncToken is collected by the GC whenether it runs.
using blocks are just a syntactic sugar of a try-finally block:
using (var myObject = new MyObject())
{
...
}
is equivalent to:
MyObject myObject = null;
try
{
myObject = new MyObject();
...
}
finally
{
if (myObject != null)
{
myObject.Dispose();
}
}
So you have the certainty that Dipose() will be called inmeadiately once you exit the using block.
An alltogether different matter is when the GC collects the object. There is no garantee of when that will happen.
The Dispose method is called as soon as your variable goes out of scope, the garbage collector will kick in at some undetermined point later and doesn't affect this.
Also, have a look at this for a simple comparison of what happens underneath:
using and IDisposable
Related
I know in the below case, using does its job to release the disposable element, i.e.
using (StreamReader sr = StreamReader(filename))
{
txt = sr.ReadToEnd();
}
However, does the same happen if I use it inline? As you see, there I don't define it as a variable:
txt = (StreamReader(filename)).ReadToEnd();
Defining or not defining a variable doesn't affect whether you need to dispose an object.
If an instance of an class which implements IDisposable is created, you should call Dispose on it when you're finished with it.
You can do that with using or manually calling Dispose - a using statement is usually more convenient and fool-proof.
Firstly, the dispose method exists to allow the developer of the class (in this case System.IO.StreamReader) to release any unmanaged resources they may be holding on to (and a lot of people use it for general cleaning up).
As a rule, if a class implements IDisposable (and therefore contains a Dispose method) it should most definitely be called.
The using statement you have used above would be compiled into the following:
//Very roughly your code sample
using (var sr = new StreamReader())
{
//Some code
}
//What gets spat out by the compiler
var sr = new StreamReader();
try
{
//Some code
}
finally
{
sr.Dispose();
}
As you can see, this pattern means that Dispose will be called regardless of whether the //Some code section throws an exception of not.
Essentially, it's a C# helper so that you don't have to write the safe code above to ensure disposal of disposable objects.
Because of the obvious benefits, the question should really be "When shouldn't you use using".
The same thing does not happen in your second example as is happening in the first example. In your second example, the StreamReader will become eligible for garbage collection immediately after that line executes because you're not storing it in a variable (so it'll go out of scope). The key word here is "eligible" - there's no guarantee of when the object will actually be cleaned up. So the second line of code will result in a lock on the file being "held" until the garbage collector gets around to garbage collecting the StreamReader.
On the other hand, if you call Dispose() on the StreamReader, it'll release the lock on the file immediately without waiting for the garbage collector.
Does the using statement always dispose the object, even if there is a return or an exception is thrown inside it? I.E.:
using (var myClassInstance = new MyClass())
{
// ...
return;
}
or
using (var myClassInstance = new MyClass())
{
// ...
throw new UnexplainedAndAnnoyingException();
}
Yes, that's the whole point. It compiles down to:
SomeDisposableType obj = new SomeDisposableType();
try
{
// use obj
}
finally
{
if (obj != null)
((IDisposable)obj).Dispose();
}
Be careful about your terminology here; the object itself is not deallocated. The Dispose() method is called and, typically, unmanaged resources are released.
No it doesn't.
But that's not the fault of using statement though. It's because how the finally blocks are handled by CLR. There ARE some cases that finally blocks will not execute. If you have an unhandled exception and if the CLR thinks that executing more code will lead to more errors, it will not execute Dispose method (because it will not execute the finally block which Dispose method is compiled down to..). Therefore, be very careful and don't put your life into the execution of Dispose method.
The other cases which can cause Dispose method not being executed can be listed as:
Environment.FailFast
OutOfMemoryExceptionand StackOverflowException
Killing the process
Power loss
If the object implements IDisposable, it will be called.
From using Statement (C# Reference) by MSDN
Defines a scope, outside of which an object or objects will be
disposed.
The using statement allows the programmer to specify when objects that
use resources should release them. The object provided to the using
statement must implement the IDisposable interface. This interface
provides the Dispose method, which should release the object's
resources.
Assuming I have a method public static Rectangle DrawRectangle(Vector origin, Vector size) which returns an object of type Rectangle : IDisposable
If I call only the method DrawRectangle(origin, size), but do not assign the return value to a variable myRectangle = DrawRectangle(origin, size), will the compiler automatically detect this and call DrawRectangle(origin, size).Dispose(), or do I have to do it myself?
No. Point.
Eventually he finalizer does, but no. It does not automatically CALL Dispose.
If your Rectangle class implemets IDisposable, try the using( ) { ... } statment when posible.
Msdn link
The compiler builds code in to assemblies and is not responsible for any execution. The .net runtime is what runs your code and more specifically, the garbage collector deals with memory clean up. It is generally best practice to call objects that implement IDisposable inside of a using block. E.g:
using (var obj = new object)
{
... do your stuff
}
This will help the runtime understand when your object goes out of scope and clean it up earlier, but as long as you dont hold on to a reference to an object, the runtime will eventually clean it up and dispose it for you.
There are only two scenarios I can think of where the compiler automatically calls dispose; the most obvious would be:
using(var obj = ... )
{
// some code
}
which is an explicit instruction to say "at the end, whether success or failure, if obj is non-null, call obj.Dispose()". Basically it expands to:
{
var obj = ...
try {
// some code
} finally {
if(obj != null) obj.Dispose();
}
}
The other is foreach, where-by the iterator is disposed - although it gets a bit complicated, because IEnumerator doesn't specify that IDisposable is required (by contrast, IEnumerator<T> does specify that), and technically IEnumerable is not even required for foreach, but basically:
foreach(var item in sequence) {
// some code
}
could be expressed as (although the spec may say it slightly differently):
{
var iter = sequence.GetEnumerator();
using(iter as IDisposable)
{
while(iter.MoveNext())
{ // note that before C# 5, "item" is declared *outside* the while
var item = iter.Current;
// some code
}
}
}
In all other cases, disposing resources is your responsibility.
If you don't ensure that Dispose() is called, then nothing will happen until GC eventually collects the object; if there is a finalizer (there doesn't have to be, and usually isn't), the finalizer will be invoked - but that is different to Dispose(). It may (depending on the per-type implementation) end up doing the same thing as Dispose(): but it may not.
If you want the CLR to call the Dispose method, it is usually recommended to implement the so called Dispose pattern in your class. However, I would not rely on CLR and wouldn't wait for GC to collect an object and use the using clause instead.
I have been working on some code for a while. And I had a question:
What it the difference between these two codes ?
using (FORM formExemple = new FORM ())
{
formExemple.ShowDialog();
}
and
FORM formExemple = new FORM ();
formExemple.ShowDialog();
using calls the object's Dispose() method to clean up after itself when it's done. It usually handles things like closing open connections and/or freeing up memory. If you instantiate it otherwise, you have to do that manually. You can only use using on objects that implement the IDisposable interface, which ensures that a method Dispose() exists for the object.
The using block is used to automatically dispose of an object that implements IDisposable.
The first gets Dispose() called at the end of the block. The using block will also ensure that the object is properly disposed of in the case of an Exception.
The second doesn't and needs to be handled by the developer when they're sure that they will no longer need the object.
As ever, consult the documentation - either the MSDN C# guide for using statements or the C# specification (it's section 8.13 in the C# 5 specification).
The using statement can only be used with types implementing IDisposable, and it basically makes sure that whatever resource appears in the inital expression (the resource acquisition expression) is disposed at the end of the block, even if an exception is thrown. Your first code snippet is broadly equivalent to:
FORM formExemple = new FORM(); // I hope you don't *really* use these names
try
{
formExemple.ShowDialog();
}
finally
{
formExemple.Dispose();
}
There's a little bit more to it than that, mind you:
The scope of any variable declared in the resource acquisition expression is the using statement itself
It copes with null values
It copes with changes to the variable within the using statement (the original value is still disposed)
Basically, it makes it easier to clean-up resources which require timely disposal - network streams, file handles, database connections, graphics objects etc.
using is something you can use with objects that have implement the IDisposable interface. The reason to use using is once you are done with your form, you don't have to worry about any clean up, the Dispose method on Form will be called and everything will be cleaned up.
In your second example, Dispose is never called and the objects are still in memory and could be for awhile if the garbage collector doesn't recognize that it needs to clean it up.
The using-statement ...
using (Font font1 = new Font("Arial", 10.0f))
{
byte charset = font1.GdiCharSet;
}
... is a syntactic shortcut (syntactic sugar) for the following pattern:
{
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
}
(I took the the example from the link above)
... and therefore the difference between your two code-snippets the try + the call to IDisposable.Dispose() in the finally-block.
The using statement defines the scope for formExemple, the memory allocated for formExemple will be freed once outside the control of the using statement.
What is better, the using directive, or the dispose directive when finished with an object?
using(FileStream fileStream = new FileStream(
"logs/myapp.log",
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
{
using(StreamReader streamReader = new StreamReader(fileStream))
{
this.textBoxLogs.Text = streamReader.ReadToEnd();
}
}
On the other hand, when I'm dealing with System.Net.Mail, I'm told I need to Dispose() of the object to release any stray locks.
Is there any consistent guidance? How do I tell what is more appropriate in a given situation for a given object?
The using statement (not directive) involves an implicit call to Dispose(), in a finally block. So there is no contradiction here. Can you link to that discussion?
The official definition of
using (x) { ... }
is
try ... finally if (x != null) x.Dispose(); }
What is better?
From a notational perspective, the using() { } block. Technically they are the same.
It's the same thing. Usage is simple, if you create the object and use it in only one method then use using. If you need to keep it alive beyond the method call then you have to use Dispose().
The runtime callable wrappers for COM objects don't have a Dispose() method.
There's no reason that I can think of to manually call Dispose(), other than in another implementation of Dispose() (for example in a class you've created that implements IDisposable) when you can wrap an object in a using block. The using block puts the creation and disposal of the object in a try/catch/finally block to pretty much gaurantee that the object will be disposed of correctly.
The compiler is more reliable than me. Or you. =)
MSDN documents the using statement and calls out where you can obtain the C# language specification where you can review section 8.13 "The using statement" (at least in the v4.0 reference it's 8.13) that gives a comprehensive explanation of the using statement and how to use it. The fifth paragraph gives the following:
A using statement is translated into
three parts: acquisition, usage, and
disposal. Usage of the resource is
implicitly enclosed in a try statement
that includes a finally clause. This
finally clause disposes of the
resource. If a null resource is
acquired, then no call to Dispose is
made, and no exception is thrown.
using(foo)
{
foo.DoStuff();
}
is just syntactic sugar for this:
try
{
foo.DoStuff();
}
finally
{
if(foo != null)
foo.Dispose();
}
So I'm not sure where the debate comes from. using blocks do call dispose. Most people prefer using blocks when possible as they are cleaner and clearer as to what is going on.
As long as the lifetime of the object is within a block of code, use using, if your object needs to be long lived, for example to be disposed after an asynchronous call you need to manually call Dispose.
A using block is way better than you of remembering the call to Dispose in all possible and impossible ways execution can leave a block of code.
using calls Dispose upon exit. using is better because it assures calling dispose.
using blocks automatically call Dispose() when the end of the block is reached.
There is one really important reason to use the "using statement" anywhere you can.
If the code that wrapped via using statement threw an exception, you could be sure that the "using object" would be disposed.