ADO.net應該手動釋放資源。

本來對於C#的GC有諸多爭議,像我這樣從僞C++程序員轉過來的,自然對於靠第三方回收堆上對象的行爲,感到一種恐懼和無力。但是,既然Java和C#都有GC,總還認爲是可靠的,但是,誰知道這個可靠的GC缺出問題了。

案例:同事做的一個操作數據庫的B/S小程序出問題了,前臺asp.net,數據庫SQL2k,操作數據庫用了ADO.net,操作幾次之後,頁面報錯,Debug時發現asp.net報錯的大意爲在connection時連接池超過了等待時間。

我們首先懷疑數據庫連接太多,但是查詢分析器直接連接數據庫正常。

其次,懷疑asp.net的連接池出錯,在連接字符串加了min和max之後,發現問題仍然存在。

再次,查源代碼,同事說這是網上共享的源碼,邏輯很簡單,看了之後,第一反應就是隻有connection.Open,沒有Close();轉念一想,C#不是有GC麼,另外在博客園的博客中也有人提到使用using強制是否資源,對Linq to SQL,有時候會產生意想不到的問題,不建議。作爲C#二把刀的我,類比到ADO.net 想來也應該是讓GC來回收資源比較好。

結果查了半天,沒有發現問題所在,只能再次加大了連接池的max,問題仍然會出現。

之後,翻閱了網上關於連接池的資料,提到

1、GC的回收是針對惡劣環境才進行的。

2、GC只回收託管資源,不回收非託管資源

3、對於連接池,在Connection.Open的時候,ado.net直接問連接池要現有連接,如果沒有空閒的 ,則等待,超過等待時間,則返回time expired。

GC沒有按照作用域回收資源->Connection沒有關閉->連接池連接全部處於使用->新增Connection.Open請求失敗,於是time expired

因此,正好手頭有個項目是用ADO.net,從此發現GC也不可靠,還是手動來吧。

特此記錄,可以自動釋放資源的操作

1、

SqlDataReader dr= myCommand.ExecuteReader(CommandBehavior.CloseConnection)

關聯的conn需要手動打開,但是SqlDataReader讀完後自動關閉。


2、

SqlDataAdapter

對於關聯的conn,在SqlDataAdapter.Fill()時會自動打開,完畢後會自動關閉。

一般程序對於SqlDataAdapter建議手動Dispose()原因不明。

3、

SqlConnection

用完一定要Close()或者Dispose(),差別是Close的可以Open,Dispose的不能了,因爲ConnectionString=String.Empty了,見傳送門


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章