美文网首页
C#中关于非托管资源的释放

C#中关于非托管资源的释放

作者: Will_板凳 | 来源:发表于2020-02-22 19:27 被阅读0次

    托管资源与非托管资源的区别

    资源分为托管资源和非托管资源。

    • 托管资源是指由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类型的字段,作为释放资源的标记

    相关文章

      网友评论

          本文标题:C#中关于非托管资源的释放

          本文链接:https://www.haomeiwen.com/subject/rtkrqhtx.html