托管资源与非托管资源的区别
资源分为托管资源和非托管资源。
- 托管资源是指由CLR管理分配和释放的资源,也就是我们直接new出来的对象;
- 非托管资源是指不受CLR控制的资源,也就是不属于.net本身的功能,往往通过调用跨平台程序集(如C++)或者操作系统提供的一些接口,比如Windows内核对象、文件操作、数据库连接、socket、win32API、网络等。
标准的显式释放资源
public class MyClass : IDisposable
{
/// <summary>
/// 模拟一个非托管资源
/// </summary>
private IntPtr NativeResource { get; set; } = Marshal.AllocHGlobal(100);
/// <summary>
/// 模拟一个托管资源
/// </summary>
public Random ManagedResource { get; set; } = new Random();
/// <summary>
/// 释放标记
/// </summary>
private bool disposed;
/// <summary>
/// 为了防止忘记显式的调用Dispose方法
/// </summary>
~MyClass()
{
//必须为false
Dispose(false);
}
/// <summary>执行与释放或重置非托管资源关联的应用程序定义的任务。</summary>
public void Dispose()
{
//必须为true
Dispose(true);
//通知垃圾回收器不再调用终结器
GC.SuppressFinalize(this);
}
/// <summary>
/// 非必需的,只是为了更符合其他语言的规范,如C++、java
/// </summary>
public void Close()
{
Dispose();
}
/// <summary>
/// 非密封类可重写的Dispose方法,方便子类继承时可重写
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (disposed)
{
return;
}
//清理托管资源
if (disposing)
{
if (ManagedResource != null)
{
ManagedResource = null;
}
}
//清理非托管资源
if (NativeResource != IntPtr.Zero)
{
Marshal.FreeHGlobal(NativeResource);
NativeResource = IntPtr.Zero;
}
//告诉自己已经被释放
disposed = true;
}
}
实例化的时候,把这个类using起来:
using(var mc = new MyClass())
{
}
步骤
- 1、实现Dispose方法
- 2、提取一个受保护的Dispose虚方法,在该方法中实现具体的释放资源的逻辑
- 3、添加析构函数
- 4、添加一个私有的bool类型的字段,作为释放资源的标记
网友评论