代码之家  ›  专栏  ›  技术社区  ›  theburningmonk

何时需要管理托管资源?

  •  4
  • theburningmonk  · 技术社区  · 16 年前

    我一直在研究标准的Dispose模式,我只是想知道我需要写什么来释放托管资源?如果这些资源已经被“管理”,那么我肯定不需要做任何事情。

    如果是这样,并且我的类不包含任何非托管资源(因此不需要由GC完成),那么我是否只需要在Dispose方法中取消完成?-

    public void Dispose()
    {
       GC.SuppressFinalize(this);
    }
    

    所以假设这是我的课:

    public sealed class MyClass : IDisposable
    {
        IList<MyObject> objects; // MyObject doesn't hold any unmanaged resource
        private bool _disposed;
    
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    
        private void Dispose(bool disposing)
        {
            if (!_disposed)
            {  
                // do I need to set the list to null and 
                // call Dispose on each item in the list?
                if (disposing)
                {
                    foreach (var o in objects)
                        o.Dispose();
    
                    objects = null;
                }
            }
    
            _disposed = true;
        }
    
        ~MyClass()
        {
            Dispose(false);
        }
    }
    

    我真的需要释放这里的管理资源吗?

    谢谢,

    3 回复  |  直到 10 年前
        1
  •  4
  •   Brian Rasmussen    16 年前

    如果你们班有 IDisposable 实例,您使用的是托管资源,因此应该实现 不可分的 允许用户处置资源。您的 Dispose 方法应调用 处置 在管理资源上。

    至于释放托管内存,您不需要做任何事情。它由GC处理,但这是GC处理的清理的唯一部分。托管和非托管资源必须由 处置 和/或终结器。

    如果不使用任何托管或非托管资源,则无需实现这两者 不可分的 也不是定稿人。实现终结器实际上会影响类型的性能,因此除非需要,否则不要实现它。

        2
  •  3
  •   LukeH    16 年前

    您应该释放实现的任何托管对象 IDisposable .

    你打不到电话 Dispose 在不实现的对象上 不可分的 所以你需要检查一下。(显然,如果 MyObject 将始终执行 可识别 那你就不需要那张支票了。)

    不需要将列表本身设置为 null .

    在一般情况下,我可能会重新编写循环,使其看起来像这样:

    if (disposing)
    {
        foreach (var o in objects)
        {
            var d = o as IDisposable;
            if (d != null) d.Dispose();
        }
    }
    

    (顺便说一下,如果你的班级没有 可识别 对象或非托管资源,那么您可能不需要实现 不可分的 或者是决赛选手。)

        3
  •  2
  •   Community Mohan Dere    8 年前

    实现IDisposable有两个原因:
    1。释放未管理的资源。这个病例非常罕见,但不幸的是,很多医生都在谈论这个病例。 这是关于释放什么 -即避免资源/内存泄漏。
    2。释放托管资源。这是常见的——这不是为了确保释放的内容(因为托管资源在某个时刻总是被GC释放),而是 关于什么时候释放 . 也就是说,它让对象的用户控制何时释放托管资源(即何时关闭套接字或文件等),以便其他东西可以访问它们。

    在您的情况下,您可以摆脱以下问题 minimum dispose 如果没有派生类添加托管资源:

    public virtual void Dispose() {
        foreach (var o in objects) {
            var d = o as IDisposable;
            if (d != null) d.Dispose();
        }
    }
    
    推荐文章