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