利用using和try-finally來釋放資源
我以前寫過一篇文章,關於.Net資源釋放問題,也就是對於非內存的資源,最好使用IDisposable接口提供的Dispose來釋放,
很明顯,Dispose方法是一個外部方法,系統並不會幫你調用。爲了儘早釋放對象所佔用的資源,所以需要保證Dispose方法能儘早被執行。那麼在.Net中提供了一個比較簡便的方法,就是對於實現了IDisposable接口的類型對象提供了using語句。
就操作一個數據庫這個例子來說,使用using語句可以如下:
using( SqlConnection sqlConn = new SqlConnection( yourConnectionString ) )
{
sqlConn.Open();//Open connection
//Operate DB here using "sqlConn"
sqlConn.Close();//Close connection
}
但是有時候當多個對象需要釋放的候,例如:
SqlConnection sqlConn = new SqlConnection( yourConnectionString );
SqlCommand sqlComm = new SqlCommand( yourQueryString, sqlConn );
using(sqlConn as IDisposable)
using(sqlComm as IDisposable)
{
sqlConn.Open();//Open connection
sqlComm.ExecuteNonQuery();//Operate DB here
}
這時候要特別注意,需要確保在發生異常的情況下,所有對象都能正常釋放。顯然,這段程序塊,當構造“sqlComm”對象發生異常,會造成“sqlConn”對象無法及時被釋放。雖說構造函數內部很少發生異常,或者說編寫程序的時候要儘量避免從構造函數內向外散發異常。不過這裏所說的意思是,要儘量把需要釋放的對象放到using或者try-catch程序塊,並作局部的異常處理,避免異常造成有些對象沒有被釋放。那麼改進的方法,例如可以如下。
using( SqlConnection sqlConn = new SqlConnection( yourConnectionString ) )
using( SqlCommand sqlComm = new SqlCommand( yourQueryString, sqlConn ) )
{
try
{
sqlConn.Open();//Open connection
sqlComm.ExecuteNonQuery();//Operate DB here
}
catch( SqlException err )
{
MessageBox.Show( err.Message );
}
catch( Exception err )
{
MessageBox.Show( err.Message );
}
}
但是對於using程序塊來說,它有兩個限制。
第一個就是using所對應的對象必須繼承IDisposable,如果此對象沒有繼承IDisposable接口的話,系統會提示編譯錯誤。
例如:
using( string strMsg = "My Test" )
Debug.WriteLine( strMsg );//Can't be compiled
第二個using對象檢查是靜態類型檢查,並不支持運行時類型檢查,因此如下形式也會出現編譯錯誤。
SqlConnection sqlConn = new SqlConnection( yourConnectionString );
object objConn = sqlConn;
using ( objConn )
{
Debug.WriteLine( objConn.ToString() );//Can't be compiled
}
不過對於後者,可以通過“as”來進行類型轉換方式來改進。
SqlConnection sqlConn = new SqlConnection( yourConnectionString );
object objConn = sqlConn;
using ( objConn as IDisposable )
{
Debug.WriteLine( objConn.ToString() );
}
對於Dispose函數的調用來說,使用using程序塊來完成只是最常用的方法,除此外,還可以用try-finally來完成,例如:
SqlConnection sqlConn = new SqlConnection( yourConnectionString );
try
{
sqlConn.Open();
//Operate DB here using "sqlConn"
}
finally
{
if( sqlConn != null )
sqlConn.Dispose();
}
爲了及早釋放對象所佔用的非託管資源,因此要保證Dispose方法能在使用完對象後被調用,.Net提供了using程序塊和try-finally程序塊兩個方法,兩者並沒有太大的區別,可能使用using能使程序看得比較簡明,但是爲了防止異常,需要在using中加入try-catch,這樣反而不如try-finally看得舒服,不過這也只是我個人的看法。總的來說,只要把方法合理整合到應用程序當中纔是最重要的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.