Is this object will dispose automatically when encounter exception? - c#

using(YourType yourObject = new YourType())
{
//Treatment on you object
//Exception occurs here
}
when we write this way, the garbage collector automatically disposes the object, but is exceptions occurs inside this will the garbage collector still dispose the object or I have to write something for it, I know this is a lame q but m really confused, thnx
please explain the treatment in different .net frameworks to make things crystal clear.

Yes, the using block will still call Dispose on an exception. See MSDN documentation.
The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object.
Also another useful article Avoiding Problems with the Using Statement.

From MSDN Documentation
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.
using (var object = new Object())
{
object.DoSomething();
}
equal with:
var object = new Object();
try
{
object.DoSomething();
}
finally
{
object.Dispose();
}

Related

How I safely dispose a variable?

What is an alternate/better way I can safely dispose of the variables purge and factory in the following code?
public void Run( string XmlFragment ) {
XmlNode xmlNode = null;
try
{
xmlNode = Common.ConstructXmlNodeFromString(XmlFragment, "Params");
var list = DataList();
foreach (var item in list)
{
var factory = new PurgerFactory(item);
IPurger purge = factory.Purger;
purge.Purge();
purge = null;
factory = null;
}
Common.PurgeEmail(SuccessEmail());
}
catch (Exception ex)
{
string errorMessage = $"Purge Error: {ex.Message}. {Environment.NewLine} Stack Trace: {ex.StackTrace}";
Common.PurgeEmail(FailEmail(errorMessage));
}
}
As I think you know, C# has a garbage collector. So for normal objects that don't access an unmanaged resource, just letting the garbage collector clean them is fine.
If you want to deterministically close a managed resource the primary paradigm is inheriting from IDisposable and a using statement. This will call the Dispose function upon exiting the code block of the using statement.
If you otherwise want to clean stuff up, but you don't care when it happens you can use ~(MyType). This is called when the GC does a GC cycle, this is called the Finalizer. I personally haven't encountered a use-case for this vs IDisposable. But if you just want to make sure say a file, or otherwise is deleted when this email object is Garbage Collected, then it might be a good use case for you.
Your code doesn't indicate whether purge or factory implement IDisposable. If they do, you would call
purge.Dispose();
factory.Dispose();
or use using which ensures that Dispose is called even if the method throws an exception:
using(var factory = new PurgerFactory(item))
{
// do stuff
} // factory is disposed.
What we don't need to do is set variables to null. An object gets garbage collected sometime after there are no longer any references to it. It's true that setting factory = null removes that reference to the object, but the same thing happens anyway when the variable goes out of scope. So it's redundant.
There's really no need to try to force that to happen sooner. It's not like the object will get garbage collected the instant there are no more references to it, so we don't worry so much about that.
In this case, the variables are both declared within the foreach loop, so the references go out of scope immediately after each iteration of the loop. In other words, they already go out of scope right at the point when you're setting them to null.
That's part of what's awesome about .NET. Imagine if we had to set every reference variable to null. We'd need try/catch everywhere to make sure it happened. It would be as if every single object was disposable. What a nightmare. Instead it's handled for us in most normal scenarios so that we don't have to think about it or clutter our code with it.

implementing IDisposable interface and what happens when exception is thrown

I have a class that implements the interface IDisposable. My understanding is that when you have finished using the object (something like the line below) the Dispose method is called to make sure everything is cleaned up - is that correct?
myObj = null;
I also would like to know if an exception is thrown whether the Dispose method still gets called? Or should I just be using a 'using' block?
My understanding is that when you have finished using the object (something like the line below) the Dispose method is called to make sure everything is cleaned up - is that correct?
No, it is not correct. Setting an instance of an object to null will not call its Dispose method, you should do that explicitly when you're done with an object.
myObj.Dispose();// Im done with myObj!
This is often done by utilizing using
using(var myObj = new MyObject())
{
myObj.DoSomething();
} // Dispose automatically called.
The above ensures Dispose is called, even if an exception is thrown within the using block.
Dispose should be explicitly called if want to release the system resources used by this object at that particular moment . If we are not calling the Dispose , the system will take care of this at some point with Garbage Collector .
If an object implementes System.IDisposable then we will be able to call the dispose method on it.
Using will be converted in to try, finally block by CLR and the dispose method will be called the in the finally block to release the resources.
Check this link for all information you required like how system handles this and all Using Statement
Just copying the code from the mentioned link to make it more useful.
If you have some code like this
using (MyResource myRes = new MyResource())
{
myRes.DoSomething();
}
Then it get's automatically converted to
MyResource myRes= new MyResource();
try
{
myRes.DoSomething();
}
finally
{
// Check for a null resource.
if (myRes!= null)
// Call the object's Dispose method.
((IDisposable)myRes).Dispose();
}

Using statement usage

If MyClass implements IDisposable interface, will the both given snippets disposes MyClass object correctly? and which method is preferable over the other?
Code 1
public MyModel MethodOne()
{
using (MyClass myClass = new MyClass())
{
var myModel = new MyModel();
myModel.MyModelData = myClass.GetData();
return myModel;
}
}
Code 2
public MyModel MethodTwo()
{
var myData = new MyData();
using (MyClass myClass = new MyClass())
{
myData = myClass.GetData();
}
var myModel = new MyModel();
myModel.MyModelData = myData;
return myModel;
}
It is the same: the object will be disposed in both way.
the using statement is translated by the compiler as a try block which calls Dispose in a finally block.
finally is guaranteed to execute after the try block has finished execution, regardless of its execution path.
Dispose is guaranteed to be called, no matter what.
Reference MSDN
As a style and best practice IMHO it is better to dispose an object as soon as it is not needed anymore because you will free resources earlier and because if Dispose throw an exception you will have your method return anything. and it will be easier to debug.
Update
As KrisVandermotten pointed out there are some cases where the finally block will not execute.
Environment.FailFast
the Uncatchable execeptions
Power Failure
using is translated to try with finally block. Your code
using (MyClass myClass= new MyClass())
{
myData = myClass.GetData();
}
Is the same as
MyClass myClass= new MyClass();
try
{
myData = myClass.GetData();
}
finally
{
if (myClass != null)
((IDisposable)myClass).Dispose();
}
As for which method is preferable, both solutions will work fine. The second one disposes of the object earlier and for that reason is preferable, in many cases. There's no need to hold on to objects, especially if they use external resources.
There are exceptions to that, though. You may want to or need to hold on to an object for longer to achieve your objective, e.g. when using a transaction scope. Also, sometimes the objects derived from the disposable object (as in your case) may become invalid if the originating object is disposed.
In both cases, you can rely on the fact that, if an object of MyClass was constructed and the method completes, the object is also disposed.
In the latter case, the object is constructed later than in the first case, and it is disposed earlier than in the first case, but in both cases it will be disposed.
Which is better? Assuming that a disposable object somehow holds on to something that needs to be freed, and that this holding on to it is expensive, all else being equal, the better approach would be the second.
So why the two caveats above?
"if an object of MyClass was constructed"
In the second case, it is possible that the call to new MyData() throws an exception, and the MyClass object construction is not even attempted. In the first case, constructing this object is the first thing that happens. It may fail, but it will be tried. It may fail in the second case as well of course. And if it fails, there is nothing to be disposed.
"and the method completes"
Nothing will be disposed if you lose power before the dispose can be executed, and there are a few other pathological cases where execution of a finally block is not guaranteed.
IMHO the first version is more concise and therefore better, since the extra time taken before disposing is likely to be negligible. It typically doesn't take long to construct a couple of objects and set a property.
Only if there were a call to "myModel.DoSomethingThaTakesALongTime()" would I consider using the second version.

Using statement with try catch. What happens to instance from using statement?

If I have a using block surrounding a try catch statement what will happen to the object inside that using statement should the catch fire an exception? Consider the following code:
using (IDatabaseConnectivityObject databaseConnectivityObject = new DbProviderFactoryConnectionBasicResponse())
{
try
{
Foo();
}
catch (ArgumentNullException e)
{
throw;
}
}
If we assume Foo() fails and the exception is fired and effectively breaks the program will databaseConnectivityObject be disposed? The reason this is important is that the object has a database connection associated with it.
You can think of using as a short-hand for try-finally. Hence your code is equivalent to:
IDatabaseConnectivityObject databaseConnectivityObject = new DbProviderFactoryConnectionBasicResponse();
try
{
try
{
Foo();
}
catch(ArgumentNullException e)
{
throw;
}
}
finally
{
if(databaseConnectivityObject != null)//this test is often optimised away
databaseConnectivityObject.Dispose()
}
Looked at this way, you can see that the Dispose() will indeed be called if the exception throws, because the try-finally is outside of the try-catch.
This is precisely why we use using.
we assume Foo() fails and the exception is fired and effectively
breaks the program will databaseConnectivityObject be disposed?
Yes it will be. using internally uses try-finally, (using only works for those which implements IDisposable)
From MSDN- using statement
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.
Yes your using block will dispose of the databaseConnectivityObject, irrespective of whether you have a try - catch block.
You rightly say that the using block is important and you should use it for all classes that implement IDisposable to ensure that they get disposed of properly even in the event of an exception.
From MSDN- using statement
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.
When implementing the using block the object in the parentheses will be disposed if it implements the IDisposable interface.
It would still be disposed even if foo() failed.
The object inside the using statement must implement the IDisposable interface.
Also, these questions "Uses of using in c sharp" and "using statement vs try finally" speak further on the uses and practicalities of the using statement.
Section 8.13 of the C# Language Specification details the using statement clearly.
Your using code is equivalent to
IDatabaseConnectivityObject databaseConnectivityObject = new IDatabaseConnectivityObject ();
try
{
//To do code here
}
finally
{
if(databaseConnectivityObject!=null)
{
databaseConnectivityObject.Dispose();
}
}
A using statement mainly categorized into three part i.e.
Acquisition
Usage
Disposal
Firstly, the resources is acquired and the usage is made on the try block with finally statement.At last, the object is disposed in finally block as given in above equivalent code....

Isn't it redundant to dispose of an object inside its own using block?

While programming over an existent class, I've noticed that someone has written something like this:
using(DisposableObject disp = new DisposableObject())
{
...
...
disp.Dispose()
}
And then I wonder: isn't the using block enough to dispose an object? Could be there any way Dispose() can be useful in such case?
Cause it doesn't make any sense to me...
In your case it is useless to use dispose inside using because when using statement's scope ends it automatically calls dispose. That's why you can only write objects which implements IDisposable Interface inside using brackets.
using(.......)
Moreover if there was any statement using disp object after disp.Dispose() it would give an error, because by then object would have been disposed, i.e. its memory has been released.
But beware
If dispose is last line before using scope ends then it is useless.
But it is not useless when there are more lines after dispose.
Yes, a using block is actually equivalent to and an alternative syntax for:
var d = new DisposableObject();
try
{
d.DoSomething();
}
finally
{
if(d != null)
((IDisposable)d).Dispose();
}
Note that it uses finally instead of something like 'catch'. The finally-clause will always be executed, even if there's an exception.
using is enough. There is no reason to call Dispose twice.
There are two reasons why you can use Dispose inside a using block:
you want to dispose the object before the using block ends. In this case the using block is a "safety net" that ensures you that your object will be disposed even if an exception happens. (using behaves like a try block which has a finally block in which your object is disposed)
calling Dispose makes more clear what you're doing. This is typical, i.e. of
transaction scopes:
using(TransactionScope ts=new TransactionScope)
{
...
if (cond)
{
ts.Complete();
}
else
{
ts.Dispose(); // makes it clear you're rolling back the transaction
}
}
This call to Dispose it's not neccesary, but it's "explanatory". It makes more obvous that the transaction is rolled back.
#Nikhil Agrawal is right. One thing I need mention is when you implement Idisposable interface, you should make sure it can be invoked many times. That's mean you should do some validation.

Categories

Resources