日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

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

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

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

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

在.NET中,絕大多數的類都是運行在托管的環境下,所以都由GC來負責回收,那么我們就不需要實現IDispose接口,而是由GC來自動負責??墒怯幸恍╊愂褂玫氖欠峭泄苜Y源,那么這個時候,我們就應該去實現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();

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

假設說我們寫了這樣的代碼:

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就沒有關閉,只能等待Finalize去關閉了。

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

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就讓代碼優雅了很多,這也是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(); }

?

代碼量是不是小了很多呢?優雅了許多呢!

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

接下來,再來看下我們常用的使用數據庫的方式:

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語句來將之代碼重構:

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();}}

這樣就好了!

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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。