using肯定所有人都用過,最簡單的就是使用using引入命名空間,然后就是引入別名,簡化輸入,本文主要介紹第三種用法,即用using強制對象清理資源。
先看下面這段代碼:
try { using (SqlConnection con = new SqlConnection(source)) { //open connection con.Open(); //do something con.Close(); } } catch (SqlException e) { //log the exception }
代碼很簡單,就不多說了,這里用using的目的就是為了保證數據庫連接這個“稀缺”資源,在使用完畢之后能夠立即關閉,即使在using語句塊執行時發生異常,在退出時,依然會將該連接關閉。
用法就是這樣,很簡單,下面說一下這段代碼執行的時候CLR為我們做了哪些工作。
IDisposable接口
必須是實現了IDisposable接口的對象才可以使用using來管理。而實現了該接口就意味着需要實現其中的Dispose方法,這個方法就是在using語句塊執行結束之后要執行的方法,對於對象資源的處理也在這個方法中進行。下圖為上述代碼中using語句塊對應的IL代碼,從圖中紅色線條圈出的部分可以看出,using語句塊最后自動執行了對象的Dispose方法。
如何保證using語句塊執行結束之后,Dispose方法一定能執行呢,看一下上圖中藍色線條圈出的兩處,大家就會明白,這里CLR也沒有多高明的實現,依舊是try...finally語句塊來保證的,只是這個try....finally語句塊不需要我們添加,CLR會自動為我們處理。
Dispose與終結器(或者叫Finalize方法 or 析構函數)
Dispose方法可以主動調用(如通過using或close方法),從而盡快的釋放本地資源,而Finalize則是需要等到GC回收該對象的時候才會被調用,一般Finalize方法用來確保當托管對象的內存被釋放時,本地資源不會泄露。
Dispose與close方法
Dispose與close方法的區別:一般情況下如果實現了IDisposable接口,那么建議在實現close方法的時候調用Dispose方法,另外在using語句塊結束時CLR會自動調用對象的Dispose方法。它們都是為了清理對象中包裝的本地資源,然后等待垃圾回收器自動回收該對象本身占用的內存。
說了半天其實還是一句話:借來的資源,用完了千萬趕緊趕緊還回去啊,地主家沒有余糧了!
寫這篇文章的時候正好看到了下面這篇文章,很揪心,真想問問那些人,你們這么做,良心上真的過得去嗎?晚上睡覺真的能踏實嗎??
替兩個逝去的生命默哀!!