在处理时废除托管资源

时间:2011-08-11 16:25:41

标签: c# .net garbage-collection idisposable

  

可能重复:
  Any sense to set obj = null(Nothing) in Dispose()?

我理解这个问题是否重复,但我在调整一些关于此主题的帖子时遇到了一些问题。

首先是一点背景。我有一个Foo类如下

public class Foo : IDisposable
{
    private Dictionary<int, string> _reallyBigDictionary = 
            new Dictionary<int, string>();

    public void Dispose()
    {
        _reallyBigDictionary = null;
    }
}

已知Foo的实例范围有限(即我知道我们不会永远保留它)。鉴于它的实例范围有限,我没有看到_reallyBigDictionary如何实际上比释放更快地释放内存。我理解它的方式,这些对象在运行垃圾收集之前不会被清除。那时,对Foo的给定实例的引用都是null,所以我希望GC能够回收那个内存。

这些帖子让我相信将成员变量设置为null没有意义:

Memory leak problems: dispose or not to dispose managed resources?

Is it better to destroy all objects or just let the garbage collector do the job?

这篇帖子让我质疑: Proper use of the IDisposable interface

有人可以为我澄清这一点吗? IDisposable实现在这里真的有必要吗?因为我无法说服自己。

3 个答案:

答案 0 :(得分:12)

您不需要IDisposable; here's why。总之,您需要遵循规则1:除非您需要,否则不要实施IDisposable

只有两种情况需要实施IDisposable

  • 该类拥有非托管资源。
  • 该类拥有托管(IDisposable)资源。

由于Dictionary<int, string>不是IDisposable,因此您的班级不应该是。{/ p>

答案 1 :(得分:0)

通过实现IDisposable接口,您可以使用Using语句确定资源的使用范围。 另外,.NET Framework中的许多类检测到一个类是IDisposable并为您运行Dispose(),这使您免除了对托管子对象进行归零的责任。

编辑----

由于评论和降价,我认为我的回答是:

.NET Framework中的许多类都实现了IDisposable - 例如许多Generic集合类型。处理这样的集合时,Microsoft实现将调用您的类的Dispose方法,检测到它实现了IDisposable。此外,还有一种情况是将对象的引用设置为null(也可能在您的Dispose方法中)。如果要删除对象的引用,请将引用设置为null。其他类可能希望维护对同一对象的引用,因此将引用设置为null的参数是错误的'是一个有缺陷的参数。使用Dispose方法将引用设置为null与以任何其他方式将其设置为null没有区别 - 已授予,但通过在IDisposable实现中执行此操作,您可以采用更加确定且防错的方式来确保发生这种情况。实现IDisposable也是实现范围界定的一种很好的方法,例如,对于事务算法等,实现IDisposable在很多方面都是有用的,只要你知道它是如何工作的以及为什么工作的原因就不必避免。令我惊讶的是,很少有.NET开发人员真正理解IDisposable接口,Finalizer,垃圾收集器和.NET最佳实践

答案 2 :(得分:-2)

在这种情况下,我认为不需要处置。它不是一个活跃的连接,它会保持开放并继续消耗资源。当你完成它的使用后,它将自行管理。

如果您确实希望确保该代码没有内存泄漏,可以尝试将以下内容添加到dispose方法中:

GC.Collect();