日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.NET,你忘记了么?(二)——使用using清理非托管资源

發(fā)布時間:2025/5/22 asp.net 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET,你忘记了么?(二)——使用using清理非托管资源 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

我們都知道,垃圾回收可以分為Dispose和Finalize兩類,關(guān)于這兩者的區(qū)別已經(jīng)太多了,一個是正常的垃圾回收GC所調(diào)用的方法,另外一個是終結(jié)器Finalizer,所調(diào)用的方法,在Effective C#一書中,有著明確的建議是說使用IDispose接口來代替Finalize。原因是因為Finalize終結(jié)會增加垃圾回收對象的代數(shù),從而影響垃圾回收。

有了上述的原因,我們現(xiàn)在只來看使用IDispose接口的類。

在.NET中,絕大多數(shù)的類都是運行在托管的環(huán)境下,所以都由GC來負責(zé)回收,那么我們就不需要實現(xiàn)IDispose接口,而是由GC來自動負責(zé)。可是有一些類使用的是非托管資源,那么這個時候,我們就應(yīng)該去實現(xiàn)IDispose接口,說個比較常用的SqlConnection之類。

寫段常用的連接SQL語句的模型:

string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Study1ConnectionString1"].ConnectionString; SqlConnection thisConnection = new SqlConnection(connectionString); thisConnection.Open(); SqlCommand thisCommand = new SqlCommand(); thisCommand.Connection = thisConnection; thisCommand.CommandText = "select * from [User]"; thisCommand.ExecuteNonQuery(); thisConnection.Close();

其實,作為非托管資源,為了防止我們忘記調(diào)用Close,一般都實現(xiàn)了Finalize,因此,即使我們沒有Close掉,也會由終結(jié)器將這塊內(nèi)存回收。但是,就增加了這塊垃圾的代數(shù)。

假設(shè)說我們寫了這樣的代碼:

string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Study1ConnectionString1"].ConnectionString; SqlConnection thisConnection = new SqlConnection(connectionString); thisConnection.Open(); SqlCommand thisCommand = new SqlCommand(); thisCommand.Connection = thisConnection; thisCommand.CommandText = "select * form [User]"; //SQL語句錯誤 thisCommand.ExecuteNonQuery(); thisConnection.Close();

這樣的話,我們打開的SqlConnection就沒有關(guān)閉,只能等待Finalize去關(guān)閉了。

這是非常不好的做法。于是,我們可以想到異常處理:

SqlConnection thisConnection = null; try {string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Study1ConnectionString1"].ConnectionString;thisConnection = new SqlConnection(connectionString);thisConnection.Open();SqlCommand thisCommand = new SqlCommand();thisCommand.Connection = thisConnection;thisCommand.CommandText = "select * form [User]";thisCommand.ExecuteNonQuery(); } finally {if (thisConnection != null){thisConnection.Close();} }

這樣做就不錯了,但是代碼看起來有些丑陋,可是使用using就讓代碼優(yōu)雅了很多,這也是C#比JAVA棒很多的地方,呵呵!

string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Study1ConnectionString1"].ConnectionString; using (SqlConnection thisConnection = new SqlConnection()) {thisConnection.Open();SqlCommand thisCommand = new SqlCommand();thisCommand.Connection = thisConnection;thisCommand.CommandText = "select * form [User]";thisCommand.ExecuteNonQuery(); }

?

代碼量是不是小了很多呢?優(yōu)雅了許多呢!

其實,在IL的位置,代碼仍然是一樣的,他同樣把代碼給編譯成了try-finally的處理形式!

接下來,再來看下我們常用的使用數(shù)據(jù)庫的方式:

string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Study1ConnectionString1"].ConnectionString; SqlConnection thisConnection = new SqlConnection(connectionString); thisConnection.Open(); SqlCommand thisCommand = new SqlCommand(); thisCommand.Connection = thisConnection; thisCommand.CommandText = "select * from [User]"; SqlDataReader thisReader = thisCommand.ExecuteReader(); thisReader.Close(); thisConnection.Close();

?

還是上面的問題,我們考慮用using語句來將之代碼重構(gòu):

string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Study1ConnectionString1"].ConnectionString; using (SqlConnection thisConnection = new SqlConnection(connectionString)) {thisConnection.Open();SqlCommand thisCommand = new SqlCommand();thisCommand.Connection = thisConnection;thisCommand.CommandText = "select * from [User]";using (SqlDataReader reader = thisCommand.ExecuteReader()){while (reader.Read()){ //操作}} }

我先把這段代碼翻譯成我們熟悉的try-finally的處理形式:

SqlConnection thisConnection = null; try {string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Study1ConnectionString1"].ConnectionString;thisConnection = new SqlConnection(connectionString);thisConnection.Open();SqlCommand thisCommand = new SqlCommand();thisCommand.Connection = thisConnection;thisCommand.CommandText = "select * from [User]";SqlDataReader reader = null;try{reader = thisCommand.ExecuteReader();while (reader.Read()){//操作}}finally{reader.Close();} } finally {thisConnection.Close(); }

更丑陋的代碼吧!所以有個原則是:盡量避免using語句的嵌套。

怎么樣解決呢?很容易,自己寫我們的try-finally吧!

SqlConnection thisConnection = null; SqlDataReader reader = null; try {string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Study1ConnectionString1"].ConnectionString;thisConnection = new SqlConnection(connectionString);thisConnection.Open();SqlCommand thisCommand = new SqlCommand();thisCommand.Connection = thisConnection;thisCommand.CommandText = "select * from [User]";reader = thisCommand.ExecuteReader();while (reader.Read()){//操作} } finally {if (thisConnection != null){thisConnection.Close();}if (reader != null){reader.Close();}}

這樣就好了!

關(guān)于using 的這節(jié)我就寫到這,最后對全文做個總結(jié),其實就是一句話:盡量使用using來進行非托管資源的資源回收。

總結(jié)

以上是生活随笔為你收集整理的.NET,你忘记了么?(二)——使用using清理非托管资源的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。