Does "using" statement always dispose the object? - c#

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.

Related

What happens if I called Dispose() before using statement end?

I have this code, I am concerned that it is "not safe"
I used Dispose() before the using statement end, for me it is slightly illogical, but it works just fine. So, is it safe?
using (FileStream stream = new FileStream(SfilePath, FileMode.Open))
{
try
{
XmlSerializer deserializer = new XmlSerializer(typeof(HighscoresViewModel));
HVM = deserializer.Deserialize(stream) as HighscoresViewModel;
}
catch (InvalidOperationException)
{
stream.Dispose();
(new FileInfo(SfilePath)).Delete();
HVM = new HighscoresViewModel();
}
}
The documentation for IDisposable.Dispose states:
If an object's Dispose method is called more than once, the object must ignore all calls after the first one. The object must not throw an exception if its Dispose method is called multiple times. Instance methods other than Dispose can throw an ObjectDisposedException when resources are already disposed.
Assuming IDisposable is implemented correctly, this use is safe. Dispose will be called a second time, and will do nothing that second time.
Well as said by #hvd that this use is safe; but it's not recommended cause if you implement Microsoft Fxcop on your code sample it will throw an Fxcop warning/error CA2202: Do not dispose objects multiple times
See here
Which says
A method implementation contains code paths that could cause multiple
calls to IDisposable.Dispose or a Dispose equivalent, such as a
Close() method on some types, on the same object.

Does the C# compiler automatically dispose of IDisposable objects?

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.

Class Members and Using Statements

Suppose a class is defined:
class TestClass
{
MemoryStream s = new MemorySteam();
void DoStuff()
{
using (s = new MemoryStream())
{
// Do stuff
}
}
}
What happens to s when the using statement exits scope?
Edit:
Will there be a problem using s in a different method?
Edit 2: Will there be an unreferenced object left undisposed from the first instantiation of MemoryStream?
It's Dispose method is called. (Note that it must implement the IDisposable interface so it can guarantee that Dispose is available)
The MSDN reference is pretty good IMO
Phil Haack also wrote an in depth article on this 7 years ago.
UPDATE TO YOUR EDIT
Once a method has had its dispose method called it will throw an exception if you try to use it outside of the scope of the method. So, yes it would be bad to reference it outside of the using. To be precise, it will throw an ObjectDisposedException
It's Dispose method is invoked.
using Statement (C# Reference)
Dispose method is called on objet in order to clean this object
We call using in order to clean non managed object, because they are not cleaned by GC
GC don't have informations about non managed object so developper must clean

Using 'using' with threading utilities in C# - when is Dispose called?

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

How do I dispose an IDisposable object if the using statement throws an exception?

How can I make sure in the following code snippet that IDataReader is disposed of if ExecuteReader throws an exception?
using (IDataReader rdr = cmd.ExecuteReader())
{
// use it
}
It makes sense to me that the using syntatic sugar does not call Dispose (since there is no instance to call it on). However, how can I be sure that the scarce resources that are normally allocated by classes that implement IDisposable will be releases?
If ExecuteReader, in your example, throws an exception it never returns anything. It is then up to the implementation of ExecuteReader to dispose of anything created before the exception.
If the constructor of an object fails to run then you do not have an object that needs to be disposed.
If you are writing a constructor which could throw an exception, you had better make sure you clean up anything you need to by using using or try-catch block.
In your IDataReader example, it is sufficient to simply dispose of the command object if the cmd.ExecuteReader() method call fails.
How about moving the code that does the initialization outside the constructor into a separate function. In essence you'll have
using (var tc = new TestClass())
{
tc.Initialize(); // setup the object. acquire expensive resources here, etc.
..more code ..
}
I thought that the using statement was translated to the IL that is similar to:
try
{
}
finally
{
disposableUsedObject.Dispose();
}
So, I would think that in normal circumstances, the Dispose should be called ?
Also, you should not throw exceptions inside the constructor , as users will not expect that an exception will be thrown when they instantiate an object.
I would move the initialization logic that can throw an exception to another method (Initialize) that has to be called after instantiating the object.

Categories