——此文章摘自《C#高級編程(第
版)》定價
元 特價
元 購買
catch ( Exception ex )
{
// Do something about the exception
}
finally
{
// Ensure that the connection is freed
connClose ( ) ;
}
在finally塊中可以釋放已經使用的任何資源這種方式的惟一麻煩是必須確保關閉連接很容易忘記在finally塊中添加關閉連接的命令所以應在編碼風格上添加一些不容易出現反常情況的內容
另外在給定的方法中可能會打開許多資源(例如兩個數據庫連接和一個文件)這樣try…catch…finally塊的層次有時可能不容易看懂但還有另一個方式可以確保資源的關閉—— 使用using語句
第二種方式—— 使用using語句塊
在開發C#的過程中NET在對象不再引用之後清理它們的方法是使用非決定性的析構方式這已經引起了一個非常熱烈的討論
在C++中對象只要使用完畢就會自動調用其析構函數這對於設計基於資源的類的人員來說是一個非常好的消息因為如果用戶忘記關閉資源使用析構函數是非常理想的只要對象使用完畢就會調用C++析構函數所以如果出現了異常但沒有捕獲有析構函數的所有對象就會調用它們的析構函數
在C#和其他托管語言中沒有自動決定性的析構方式而是有一個垃圾收集器它會在未來的某個時刻釋放資源它是非決定性的因為我們不能確定這個過程在什麼時候發生忘記關閉數據庫連接可能會導致NET可執行程序的各種問題幸運的是我們還有解決的方法下面的代碼說明了如何使用using子句確保實現IDisposable接口(詳見第章)的對象在退出塊時立即被釋放
string source = server=(local)\\NetSDK; + integrated security=SSPI; +database=Northwind;
using ( SqlConnection conn = new SqlConnection ( source ) )
{
// Open the connection
connOpen ( ) ;
// Do something useful
}
在這個示例中無論塊是如何退出的using子句都會確保關閉數據庫連接
查看一下連接類的Dispose()方法的IL代碼它們都檢查連接對象的當前狀態如果其狀態為打開就調用Close()方法浏覽NET程序集的一個強大工具是Reflector(可以從/wwwaistocom/roeder/dotnet/上獲得)這個工具允許查看任何NET方法的IL代碼還可以把IL代碼反編譯為源代碼讓我們輕松地確定給定的方法的作用
在編程時應至少使用這兩個方法中的一個或者兩個方法都使用無論在哪裡獲得資源最好都使用using ()語句因為盡管我們都會編寫Close()語句但有時會忘記此時using子句就會發揮作用這兩種方式都沒有好的異常處理方式來替代所以在大多數情況下最好組合使用這兩種方法如下面的示例所示
try
{
using (SqlConnection conn = new SqlConnection ( source ))
{
// Open the connection
connOpen ( ) ;
// Do something useful
// Close it myself
connClose ( ) ;
}
}
catch (Exception e)
{
// Do something with the exception here
}
這裡顯式調用了Close()但這是不必要的因為using子句將確保在任何情況下都執行關閉操作但是應確保像這樣的資源盡可能早地釋放因為在塊的其余部分可能有更多的代碼而在這些地方沒有必要鎖定資源
另外如果在using塊中出現了異常using子句就會確保在資源上調用IDisposableDispose方法在本例中將確保總是關閉數據庫連接這樣與必須確保在異常子句中關閉連接相比代碼的可讀性更高
最後如果編寫一個封裝資源的類無論該資源是什麼都應實現IDisposable接口關閉資源這樣任何使用該類的代碼都可以利用using()語句以確保資源被釋放
[] []
From:http://tw.wingwit.com/Article/program/net/201311/14824.html