C 釋放非託管資源

2022-06-13 08:15:11 字數 2597 閱讀 5654

c#中資源分為託管資源和非託管資源。 託管資源由垃圾**器控制如何釋放,不需要程式設計師過多的考慮(當然也程式設計師也可以自己釋放)。 非託管資源需要自己編寫**來釋放。那麼編寫好的釋放非託管資源的**(釋非**)由誰來呼叫呢。有兩種實現方式:

一 將釋非**放到建構函式析構函式中,由系統自動呼叫,系統會在資源物件不再使用了,會在某個時間呼叫建構函式析構函式來釋放非託管資源。建構函式析構函式的目的就是用來釋放或清理非託管資源的。但它有乙個問題是呼叫的時間是系統說了算,不能在程式中自己想要呼叫時呼叫析構函式,這是c#規定的。那麼就產生了第二種方式。

二 將釋非**放到另外乙個函式中,當自己想呼叫時就呼叫。將釋非**放在乙個方法中共用,**如下:

1 myclass

2 7

8 public void dispose()

9

12

13 private void disposepro()

14

18 }

但是這樣可能會產生其他問題。資源可能會被多次釋放,而產生問題。系統會自動呼叫析構函式,自己也可能多次呼叫dispose()方法。那麼解決方法是使用乙個全域性變數作為標記,來標記資源是否已經被釋放,已經釋放就不再釋放。**如下:

1   myclass

2

8

9 public void dispose()

10

13

14 private void disposepro()

15

21 disposed = true;

22 }

23 }

這樣看起來似乎沒有問題了。但是當呼叫dispose()方法只能立即釋放非託管資源,而託管資源還是需要由gc自動處理。那麼為了能夠做到呼叫dispose()方法時也能夠釋放立即釋放託管資源,則需要在disposepro()方法中新增上想要釋放的託管資源的釋放**(釋放託管**)。**如下:

1     myclass

2

8

9 public void dispose()

10

13

14 private void disposepro()

15

23 disposed = true;

24 }

25 }

這樣還是有問題,當析構函式呼叫disposepro()時,會呼叫釋託管**,可能產生問題——託管物件可能已經被gc刪除了而產生問題。那麼使用乙個標記給disposepro(),當是被析構函式呼叫時不執行釋託管**。重新命名disposepro(),**如下:

1       myclass

2

8

9 public void dispose()

10

13

14 private void dispose(bool disposing)

15

23 // 釋非**

24 ......

25 }

26 disposed = true;

27 }

28 }

用這段**來釋放資源應該沒有問題了。看一下標準清理模式,**如下:

1     myclass:idisposable

2

8

9 public void dispose()

10

14

15 private void dispose(bool disposing)

16

24 // 釋非**

25 ......

26 }

27 disposed = true;

28 }

29 }

標準清理模式中多了一句gc.suppressfinalize(this);【該方法通知clr不要呼叫該方法的析構函式,因為它已經被清理了。】如果沒有這句**,我認為不影響程式的正確性,不會發生安全問題,他只是告訴系統不要再呼叫建構函式了。那麼為什麼要加上這句**呢?如果在呼叫了dispose()之後再呼叫析構函式只是多此一舉,所以告訴系統不要再呼叫了。這一點應該和效能有關係。【如果不需要建構函式就不要執行建構函式,他們會帶來效能上的開銷】。

參考:c#4.0 **教程 daniel m. solis

1. 實現 finalize 和 dispose 以清理非託管資源 

2. gc.suppressfinalize 方法 

非託管資源的釋放

與c 一樣,c 可以定義析構函式。但c 的析構函式主要用於釋放託管資源。在net中,由gc垃圾 執行緒掌握物件資源的釋放,程式設計師無法掌控析構函式的呼叫時機。為了完全掌控非託管資源的釋放,net提供乙個idisposable介面。問題 finalize 和dispose 之間的區別?最簡單的解釋是...

非託管資源建立與釋放

現象 主程式呼叫我的dll庫無法執行 異常資訊顯示 bug exception 引數無效。system.argumentexception stack trace 在 system.drawing.graphics.checkerrorstatus int32 status 在 system.dra...

C 託管資源和非託管資源

託管資源指的是.net可以自動進行 的資源,主要是指託管堆上分配的記憶體資源。託管資源的 工作是不需要人工干預的,有.net執行庫在合適呼叫垃圾 器進行 非託管資源指的是.net不知道如何 的資源,最常見的一類非託管資源是包裝作業系統資源的物件,例如檔案,視窗,網路連線,資料庫連線,畫刷,圖示等。這...