.net托管代码和非托管代码

.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);

}

}