2011-05-19 46 views
6

如果我有这样的代码,并在第二个使用语句中发生错误,第一次使用不会调用dispose方法?嵌套使用语句 - 哪一个不会得到处理

using (System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection(cnstr)) 
{ 
     cn.Open(); 

     using (SqlTransaction tran = cn.BeginTransaction(IsolationLevel.Serializable)) 
       { 

- 编辑 -

也就是它更好地写try/finally块或using语句。内部编译器会为使用语句生成Try/Finally,但根据编码标准哪个更好?

+0

它将以相反的顺序处理它们(即内部的一个被称为第一个)。 – 2011-05-19 18:09:24

回答

11

不,两者都会被调用。仅仅因为内部语句中调用了异常,并不意味着第一个被忽略。

using语句只是另一种语法:

var iDisposableItem = new Item(); 

try 
{ 
    ...... 
} 
finally 
{ 
    iDisposableItem.Dispose(); 
} 

所以在你的榜样:

var iDisposableItem = new Item(); 

try 
{ 

    var iDisposableItem2 = new Item(); 

    try 
    { 
     throws exception 
    } 
    finally 
    { 
     iDisposableItem2 .Dispose(); 
    }  

} 
finally 
{ 
    iDisposableItem.Dispose(); 
} 

现在更要注意,你必须要小心的是,无论造成什么当它调用Dispose()时,第一个异常可能会导致外部使用语句出现问题。该异常可能会将(确实是)对象置于故障状态,调用Dispose可能会导致另一个不同的异常,它会“屏蔽”第一个异常。这是一个WFC使用疑难杂症语句using时:http://msdn.microsoft.com/en-us/library/aa355056.aspx

+0

异常冒泡,并且发布链与它一起。 – iwayneo 2011-05-19 17:44:46

+0

优秀的文章。谢谢一堆。 – Asdfg 2011-05-19 19:04:34

2

一个using说法只不过是一种变相的try/finally,除非进程被强制终止,你的对象将正确处置。

换句话说,这样的:

using (Type1 x = new Type1()) 
{ 
    // a 
    using (Type2 y = new Type2()) 
    { 
     // b 
    } 
    // c 
} 

实际上类似于此(这是简化的):

Type1 x = new Type1(); 
try 
{ 
    // a 
    Type2 y = new Type2(); 
    try 
    { 
     // b 
    } 
    finally 
    { 
     y.Dispose(); 
    } 
    // c 
} 
finally 
{ 
    x.Dispose(); 
} 
0

它将部署两者,并且可以缩短它想:

using (SqlConnection cn = new SqlConnection(cnstr), SqlTransaction tran = cn.BeginTransaction(IsolationLevel.Serializable)) 
{ 
    cn.Open(); 

} 
+0

我不认为我可以做到这一点,因为两者都是不同的类型。 – Asdfg 2011-05-19 17:53:01