Does Dispose still get called when exception is thrown inside of a using statement?
Yes, using
wraps your code in a try/finally block where the finally
portion will call Dispose()
if it exists. It won't, however, call Close()
directly as it only checks for the IDisposable
interface being implemented and hence the Dispose()
method.
See also:
- Intercepting an exception inside IDisposable.Dispose
- What is the proper way to ensure a SQL connection is closed when an exception is thrown?
- C# "Using" Syntax
- C# USING keyword - when and when not to use it?
- 'using' statement vs 'try finally'
- What is the C# Using block and why should I use it?
- Disposable Using Pattern
- Does End Using close an open SQL Connection
If an exception occurs inside a using block, is the Dispose method called?
Yes it will get called.
using
translates into try-finally
block, so even in case of recoverable exception Dispose
gets called.
See: using statement C#
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.
Consider SqlConnection
which implements IDisposable
interface, so the following:
using (SqlConnection conn = new SqlConnection("connectionstring"))
{
//some work
}
Would get translated into
{
SqlConnection conn = new SqlConnection("connectionstring");
try
{
//somework
}
finally
{
if (conn != null)
((IDisposable)conn).Dispose(); //conn.Dispose();
}
}
If an Exception happens within a using statement does the object still get disposed?
Yes, they will.
using(SPWeb spWeb = spSite.OpenWeb())
{
// Some Code
}
is equivalent to
{
SPWeb spWeb = spSite.OpenWeb();
try
{
// Some Code
}
finally
{
if (spWeb != null)
{
spWeb.Dispose();
}
}
}
Edit
After answering this question, I wrote a more in depth post about the IDisposable and Using construct in my blog.
Are resources disposed even if an exception is thrown in a using 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
IDisposable.Dispose is never called after exception in using block
Environment.Exit will terminate the program
If Exit is called from a try or catch block, the code in any finally
block does not execute. If the return statement is used, the code in
the finally block does execute.
using (var x = new Disposable())
{
throw new Exception("asdfsdf");
}
will be converted to
Disposable x = new Disposable();
try
{
throw new Exception("asdfsdf");
}
finally
{
if (x != null)
x.Dispose();
}
Does using statement always dispose the object?
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.
Using statement with try catch. What happens to instance from using statement?
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
.
Will be Disposable resource disposed if try/catch is used inside using statement?
In your case the exception is catched right inside the using and the dispose is executed when you leave the using block.
But even if you put the using block outside the try catch
and an exception is thrown, the dispose will be called.
public static void LogError(string error, string message)
{
try
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.AppSettings["connStringWeb"]))
using (SqlCommand cmd = new SqlCommand("INSERT INTO errorLogTable (errorTime, errorType, error) VALUES(@errorTime, @errorText, @errorMsg)"))
{
cmd.CommandTimeout = 300;
cmd.Connection = conn;
cmd.Prepare();
cmd.Parameters.AddWithValue("@errorTime", DateTime.Now);
cmd.Parameters.AddWithValue("@errorText", error);
cmd.Parameters.AddWithValue("@errorMsg", message);
conn.Open();
int i = cmd.ExecuteNonQuery();
}
}
catch {}
}
Unhandled Exception with Using statement
using
translates into try-finally
block, it doesn't have catch
, so you are misunderstanding the article. It will not catch
any exception, It will only make sure to dispose the object in case of an exception.
In your case since it a FileNotFound
exception, your object will not be initialized.
Your code would translate into something like:
{
TextReader sv = null;
try
{
sv = File.OpenText(@"sv\.sv");
char[] k = { ':' };
lastWsp = sv.ReadLine().Split(k)[1];
}
finally
{
if(sv != null)
sv.Dispose();
}
}
In the above code in case of exception, it will try to dispose your object sv
. But the exception will remain unhandled .
Since in your code, the exception is FileNotFound
your object sv
will remain null (uninitialized) and hence there will be no reason to call Dispose
. But imagine if you have valid file path, and you get an exception at sv.ReadLine().Split(k)[1];
then it will dispose your TextReader
sv
, and that exception will propagate up in the hierarchy because there is no catch
block.
What is the purpose of the using statement?
if I understand correctly, the using statement works like a try/finally
Correct.
so I would expect that if an exception occurs in a using statement, it should not crash the program.
Incorrect.
Neither try/finally
nor using
statements swallow exceptions - if you don't catch the exception, it will propagate up. If it's uncaught, it will usually terminate the process. (There are a few cases where it won't, based on which thread it's in and how the CLR is configured, but that's a different matter.)
But then I wonder what is the purpose of the using statement.
To make it simpler to write code that needs to dispose of resources. That's all. If we didn't have using
statements, we'd have a lot of try
/finally
blocks which just called Dispose
... and that would be considerably uglier. (Been there, done that - that was Java until Java 7 introduced the try-with-resources statement.)
Related Topics
Mongodb .Net Driver 2.0 Pull (Remove Element)
Benefits of Using Async and Await Keywords
Outofmemoryexception When I Read 500Mb Filestream
Iequalitycomparer for Sequenceequal
Visual Studio 2010: How to Enforce Build Order of Projects in a Solution
Http Error 500.19 When Publish .Net Core Project into Iis with 0X80070005
Why Does Random.Next() Always Return the Same Number
Difference Between the Keydown Event, Keypress Event and Keyup Event in Visual Studio
How to Run Commands on Ssh Server in C#
How to Programmatically List All Projects in a Solution
ASP.NET Button Onclick Event Not Firing
Cannot Convert Type 'Task<Derived>' to 'Task<Interface>'