.NET Framework 提升與COM組件、COM+服務、外部類型庫和許多操作系統服務進行交互。托管和非托管對象模型之間的數據類型、方法簽名和錯誤處理機制有所不同。 要簡化.NET Framework組件和非托管代碼之間的互操作並簡化遷移路徑,公共語言運行時(CLR)需對客戶端和服務端隱藏這些對 ...
.NET Framework 提升與COM組件、COM+服務、外部類型庫和許多操作系統服務進行交互。托管和非托管對象模型之間的數據類型、方法簽名和錯誤處理機制有所不同。
要簡化.NET Framework組件和非托管代碼之間的互操作並簡化遷移路徑,公共語言運行時(CLR)需對客戶端和服務端隱藏這些對象模型中的差異。
1.什麼是托管代碼?
在運行時(CLR)控制下執行的代碼稱為托管代碼。,通過高級語言(C#,VB,F#等)相應的編譯器將其便意味中間語言(IL),CLR將其編譯成機器代碼,然後執行。托管代碼可以通過GC垃圾回收機制進行記憶體的管理和釋放。
2.什麼是非托管代碼?
在運行時以外運行的代碼成為非托管代碼。如:COM組件、ActiveX介面和Win32 API函數都是非托管代碼的示例。非托管代碼需要手動釋放資源。
3.非托管代碼如何釋放?
通過實現Dispose方法來釋放應用程式的非托管資源。因為.net的GC垃圾回收器不分配和釋放非托管記憶體。
釋放對象的模式成為釋放模式,釋放模式僅用於訪問非托管資源的對象,如文件和管道句柄、註冊表句柄、等待句柄或指向非托管記憶體塊的指針。
釋放模式有兩種實現方式:
1.可以包裝類型再安全句柄中(System.Runtime.InteropServices.SafeHandle 派生的類)使用每個非托管資源。此情況,你可以實現IDisposable介面和Dispose(Boolean)方法。不用重寫Object.Finalize方法。
實例:
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
class BaseClass : IDisposable
{
// 標誌:配置已被調用嗎?
bool disposed = false;
// 實例化一個SafeHandle的實例。
SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);
// 公共Dispose方法
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this); }
// 實現Dispose方法
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing) {
handle.Dispose();
//在這裡釋放任何其他托管對象
//
}
//在這裡釋放任何其他非托管對象
//
disposed = true;
} }
2.實現IDisposable介面和Dispose(Boolean)方法,重寫Object.Finalize方法。如類型的使用者未調用你的Finalize實現,則必須重寫IDispose.Dispose已確保釋放非托管資源。如使用了1方式,則SafeHandle 可代替你自己的實現執行此操作。
實例:
using System;
class BaseClass : IDisposable {
bool disposed = false;
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
// 實現Dispose方法
protected virtual void Dispose(bool disposing) {
if (disposed) return;
if (disposing) {
//在這裡釋放任何其他托管對象
//
}
//在這裡釋放任何其他非托管對象
//
disposed = true;
}
~BaseClass() {
Dispose(false);
}
}