當前位置: 華文問答 > 數位

C# 裏的 dispose 的作用是什麽?

2019-06-13數位

對於托管資源交給gc就可以,但是對於非托管資源你需要手動確定時機因為系統沒辦法知道時機。舉個例子,比如網路連線,你可以用完就斷開也可以用幾年才關,gc是沒有辦法透過標記垃圾回收的參照規則真正知道你什麽時候用完,只有開發者才知道。

另外一類的資源是需要馬上釋放的,底層的實作很多是native呼叫的,比如檔控制代碼,還有底層的裝置介面等。那種東西之所以需要被設計成可以馬上釋放,是因為他們具有獨占性影響,比如你的檔加了檔鎖那麽理論上這一刻別的行程,不是你的app對它寫而期待讀怎麽辦?而gc是設計成希望開發者不關註被觸發的時機來響應的處理。但是檔存取很可能是你用完別人馬上要用這個檔哇。我們想象這樣一種情景,比如你本地有2個exe執行,a.exe負責生成一些中間數據,然後b.exe從這些中間檔讀數據來做別的處理邏輯。假設a.exe和b.exe是不同的行程,並且透過socket通訊。a處理完了,保存完了數據告訴b.exe你可以幹活了。然後這個時候a由於不知道什麽時候觸發gc,所以不知道什麽能釋放這個檔的使用權。然後你明明通知了b.exe可以幹活了。

結果b.exe等了半天,好沒好哇兄弟。結果你憋了半天硬是沒觸發gc而釋放檔控制代碼。你說這樣的設計蛋疼不?

你可能說,我自己hack一下自己呼叫一下System.GarbageCollection()哇。別做這種蠢事!如果你寫java,c#還需要手動呼叫gc,那麽說明這個程式有毒。你真正需要的是呼叫handle.Close()或者handle.Dispose()!

你不要把c#的世界理解為只有c#哇,實際上你還要合c++等其他環境開發的系統元件有互動呢。還有你要和別的行程互動呢,你怎麽跨行程控制gc的東西?那麽有沒有多個行程競爭存取資源的情況?事實上是有的哇。gc能解決一部份問題,但絕對不是全部。