微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C#典型的IDisposable模式在某些情况下不会导致资源泄漏

如何解决C#典型的IDisposable模式在某些情况下不会导致资源泄漏

下面是C#类的典型Idisposable实现,它同时具有托管和非托管资源。我的问题是,对于任何给定的对象,在某种情况下,是否存在〜disposableObject()析构函数方法调用之前的情况?并且如果可能的话,将不会将处置标志设置为false,并且如果将处置标志设置为false,则由于dispose(bool)方法不会执行任何操作,因此托管资源将永远不会被处置。

public class disposableObject : Idisposable
    {
        private bool disposed;
        private ManagedResource mgdRs;
        private UnmanagedResource unMgdRs;

        public disposableObject()
        {
            mgdRs = new ManagedResource();
            unMgdRs = new UnmanagedResource();
        }

        ~disposableObject()
        {
            this.dispose(false);
        }
    
        public void dispose()
        {    
             this.dispose(true);
             GC.SuppressFinalize(this);       
        }

        protected virtual void dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    // clean up managed resources
                    //call dispose on your member objects
                    mgdRs.dispose();
                }

                // clean up unmanaged resources
                unMgdRs.Destroy();
                this.disposed = true;
            }
        }
    }
}

解决方法

是的,终结器首先被调用是有可能的。但是,这里有三件事要理解。

首先,在C#中很少需要实现完整的IDisposable模式。仅当您拥有相同类型的托管资源和原始非托管资源时,才需要完整模式。

您处理的大多数非托管资源已经有了托管包装程序,因此不需要实现另一个终结器/析构函数。另外,实现需要终结器的原始非托管资源的开发人员通常会将自己限制为仅一个资源,这样就不会有相同类型的托管资源来与问题产生冲突。这样,非托管资源就变成了托管资源,现在可以作为更简单模式的一部分来包含。

要理解的第二件事是终结器作为垃圾收集的一部分运行。鉴于终结器正在运行,我们知道将清理非托管资源,仅保留托管资源。垃圾收集器将采用托管资源的确切定义。因此,如果终结器运行得太早,导致Dispose()调用丢失了托管资源,那就可以了,因为垃圾收集器已经在运行并且会处理。

这使我想到了第三件事。不仅可以首先调用终结器,而且在发生这种情况时,终结器很可能仅被称为 ,因为除垃圾收集器之外,调用终结器的情况非常罕见。如果垃圾回收器正在为某个对象运行,则将没有剩余的引用可用于有意或隐式调用Dispose()。同样,这没关系:终结器正在运行,因此我们知道非托管资源将被清除,垃圾回收器正在运行,因此我们也将清除托管资源。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?