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....
Related
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();
}
I just want to know is it safe/ good approach to call return inside a using block.
For ex.
using(var scope = new TransactionScope())
{
// my core logic
return true; // if condition met else
return false;
scope.Complete();
}
We know the at the last most curly brace dispose() will get called off. But what will be in the above case, since return jumps the control out of the given scope (AFAIK)...
Is my scope.Complete() get called?
And so for the scope's dispose() method.
It's perfectly safe to call return inside your using block, since a using block is just a try/finally block.
In your example above after return true, the scope will get disposed and the value returned. return false, and scope.Complete() will not get called. Dispose however will be called regardless since it reside inside the finally block.
Your code is essentially the same as this (if that makes it easier to understand):
var scope = new TransactionScope())
try
{
// my core logic
return true; // if condition met else
return false;
scope.Complete();
}
finally
{
if( scope != null)
((IDisposable)scope).Dispose();
}
Please be aware that your transaction will never commit as there's no way to get to scope.Complete() to commit the transaction.
That's fine - finally clauses (which is what the closing curly brace of the using clause does under the hood) always get executed when the scope is left, no matter how.
However, this is only true for statements that are in the finally block (which cannot be explicitly set when using using). Therefore, in your example, scope.Complete() would never get called (I expect the compiler to warn you about unreachable code though).
In general, it is a good approach. But in your case, if you return before calling the scope.Complete(), it will just trash the TransactionScope. Depends to your design.
So, in this sample, Complete() is not called, and scope is disposed, assuming it is inheriting IDisposable interface.
scope.Complete should definitely be called before return. Compiler will display a warning and this code will never be called.
Regarding return itself - yes, it is safe to call it inside using statement. Using is translated to try-finally block behind the scene and finally block is to be certainly executed.
In the example you have provided, there is a problem; scope.Complete() is never called.
Secondly, it is not a good practice to use return statement inside using statements. Refer to the following:
using(var scope = new TransactionScope())
{
//have some logic here
return scope;
}
In this simple example, the point is that; the value of scope will be null when using statement is finished.
So it is better not to return inside using statements.
In this example, scope.Complete() will never execute. However, the return command will cleanup everything that is assigned on the stack. The GC will take care of everything that is unreferenced. So, unless there is an object that can not be picked up by the GC, there is no problem.
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.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Does Dispose method still get called when Exception is thrown inside of Using statment?
I've got a number of using blocks, when accessing a database. I was wondering - if an exception had to be thrown within the using block, would the necessary resources still be disposed, even though the end of the block is not reached? Or would I need to close them myself manually in the catch block?
The resources defined with the using statement were disposed, this is the main reason what using is good for.
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.
http://msdn.microsoft.com/en-us/library/yh598w02%28v=VS.100%29.aspx
Yes, the resource of the using block will be disposed.
You wouldn't. Actually the using block is the same if you use try{}catch{}finally{} construction with Dispose method call in the finally block. So it will be called anyway.
Yes, the element will be disposed of, as the call is part of the finally block of the try into which the using translates.
From 8.13 of the C# specification:
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.
So you won't need to dispose of it manually, and I'm unsure of where your own catch block would be in this case anyway.
The using(...) statement is syntactic sugar for try{} finally {}.
But if I then have a using statement like below:
using (FileStream fs = File.Open(path))
{
}
Now I want to catch the exceptions that opening this file could cause (and this is fairly high risk code in that it can fail due to the environment), but if I write try-catch inside would that not be repetition? When the code gets compiled to IL, I assume the repetition will get deleted when the code is JITted?
However, I would want to catch the exceptions opening a file can cause (so I should wrap the try-catch outside the using statement's scope), and also the exceptions for whatever I do inside the using block so I should add the try-catch inside the block.
This seems like I am adding a lot of repetition to what the CLR probably does inside. Does the CLR add catch clauses?
My colleague argued that a using statement is messy (but this was because a single line was slightly long due to me hard coding them as I needed to change them very quickly and didn't have access to other parts of the code base). Said colleague doesn't use the using statement but is there ever any functional difference between the using statement and try-finally/try-catch-finally? I did see one case of this where WCF services have a not well known corner case about using finally and returning values (something about finally). The solution was to use a check block. Is there anything like this in C#?
On another note, are all types which implement IDisposale owners of unmanaged resources? A discussion with my friend pointed the answer to being no. (I have also read some threads in the using section of this forum, some very good knowledge there).
You can implement the pattern yourself if you need to handle some exceptions if you really want to. Personally, I still find it simpler (and more importantly, clearer) to just wrap the using in try/catch block.
But if you do it yourself, make sure you get it right. The Using block also creates an anonymous scope block so that your variable becomes eligible for collection sooner. The .Dispose() method that's called at the end of the Using block only cleans up unmanaged resources, and so any memory your object holds may hang around a little longer. It's not likely a huge concern, but it is worth remembering just in case.
So, to do a direct adaption of the pattern, your code needs to look more like this:
{
FileStream fs;
try
{
fs = File.Open(path);
}
catch (FileNotFoundException e) { /* ... */ }
catch (IOException e) { /* ... */ }
catch (Exception e) {/* ... */}
finally
{
if (fs != null) fs.Dispose();
}
}
Personally, I'd like to see Using expanded to support Catch and Finally blocks. Since they're already performing a transformation on the code, it doesn't seem like this would add that much additional complexity.
My preference would be to keep the using statement and wrap it in a try/catch. The outer try/catch will catch whatever exceptions you need to watch for, while ignoring the Dispose(). This has the added advantage of protecting you from yourself should you refactor this later to move the try/catch elsewhere (like in a calling function).
As far as your question about IDisposable: Anyone can implement this for any reason they like. There is no technical reason for it to be limited to unmanaged resources. (Whether or not it should be limited to unmanaged resources in your code is a different question).
The biggest difference between using and try-finally is that using will only call the Dispose() method. If you implement your own finally block can do other logic, for example logging, which would not be included in the using.
If you need to explicitly handle different exceptional cases which may happen during the statement, you could replace using with try/catch/finally and call Dispose() explicitly in the finally. Or you could put a try/catch around the using block to separate exceptional circumstances from ensuring disposal.
The only thing using does is ensure Dispose() is called even if an exception is thrown inside the block. That is a very limited, highly specific implementation of the general try/[catch]/finally structure.
The important thing is that none of these options have any real impact - as long as it does what you need, is readable and understandable, who cares? It's not like an extra try will be a bottleneck or anything!
To answer your last question - no, IDisposable definitely does not necessarily mean the implementer has handles to unmanaged resources. It's a far simpler and more generic pattern than that. Here's one useful example:
public class Timer : IDisposable
{
internal Stopwatch _stopwatch;
public Timer()
{
this._stopwatch = new Stopwatch();
this._stopwatch.Start();
}
public void Dispose()
{
this._stopwatch.Stop();
}
}
We can use this to time things without having to explicitly rely on start and stop being called by using:
using(Timer timer = new Timer())
{
//do stuff
}
The using construct is shorthand for a try/finally block. That is, the compiler generates:
FileStream fs = null;
try
{
fs = File.Open(path);
// ...
}
finally
{
if (fs != null)
fs.Dispose();
}
So it is proper to use using if you do not need a catch, but if you do then you should just use a normal try/catch/finally.