2011-05-19 39 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