nested using statements - which one wont get disposed
If i have some code like this and an error occurs in the second using statement, will the dispose me开发者_StackOverflow中文版thod on 1st using not be called?
using (System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection(cnstr))
{
cn.Open();
using (SqlTransaction tran = cn.BeginTransaction(IsolationLevel.Serializable))
{
--EDIT--
Also is it better to write Try / Finally block or using statement. Internally compilter will generate Try / Finally for using statement but as per coding standards which one is better?
No, both will be called. Just because an exception is called in the inner statement, doesn't mean that the first is ignored.
a using statement is just another syntax for:
var iDisposableItem = new Item();
try
{
......
}
finally
{
iDisposableItem.Dispose();
}
so in your example:
var iDisposableItem = new Item();
try
{
var iDisposableItem2 = new Item();
try
{
throws exception
}
finally
{
iDisposableItem2 .Dispose();
}
}
finally
{
iDisposableItem.Dispose();
}
Now what should be noted and what you have to be careful about is that whatever caused the first exception could cause problems with the outer using statement when it calls Dispose()
. The exception could throw the (really either) object into a faulted state and calling Dispose might result in another different exception which "masks" the first one. This is a gotcha in WFC when using using
statements: http://msdn.microsoft.com/en-us/library/aa355056.aspx
A using
statement is nothing but a try/finally
in disguise, unless the process is forcibly terminated, your objects will be disposed of correctly.
In other words, this:
using (Type1 x = new Type1())
{
// a
using (Type2 y = new Type2())
{
// b
}
// c
}
Is actually similar to this (this is simplified):
Type1 x = new Type1();
try
{
// a
Type2 y = new Type2();
try
{
// b
}
finally
{
y.Dispose();
}
// c
}
finally
{
x.Dispose();
}
It will dispose both, and you can shorten it like:
using (SqlConnection cn = new SqlConnection(cnstr), SqlTransaction tran = cn.BeginTransaction(IsolationLevel.Serializable))
{
cn.Open();
}
精彩评论