如果.NET有垃圾收集,那你为什么要显式调用IDisposable
呢?
垃圾收集用于记忆.您需要处理非内存资源 - 文件句柄,套接字,GDI +句柄,数据库连接等.这通常是IDisposable
类型的基础,尽管实际句柄在引用链中可能相当长.例如,你可能Dispose
在XmlWriter
其中配置一台StreamWriter
有一个参考,它部署在FileStream
它有一个参考,它释放的文件句柄本身.
在其他评论上稍微扩展一下:
应该对所有引用了非托管资源的对象调用Dispose()方法.这样的示例包括文件流,数据库连接等.大多数情况下工作的基本规则是:"如果.NET对象实现了IDisposable,那么在完成对象时应该调用Dispose().
但是,还要记住一些其他事项:
调用dispose并不能控制对象何时被实际销毁和释放内存.GC为我们处理这个问题并且比我们做得更好.
如Jon指出的那样,Dispose清理所有本机资源,一直到基类堆栈.然后它调用SuppressFinalize()来指示该对象已准备好被回收,并且不需要进一步的工作.GC的下一次运行将清理它.
如果未调用Dispose,则GC会将对象视为需要清理,但必须首先调用Finalize,以确保释放资源,Finalize的请求排队并且GC继续运行,因此缺少在可以清理对象之前调用Dispose强制运行一个GC.这会导致对象被提升为GC的下一代"生成".这可能看起来不是什么大问题,但在内存压力的应用程序中,将对象推广到更高代的GC可以将高内存应用程序推到墙上,成为内存不足的应用程序.
除非绝对需要,否则不要在自己的对象中实现IDisposable.实施不当或不必要的实施实际上可以使事情变得更糟而不是更好.这里有一些很好的指导:
实现Dispose方法
或者阅读关于垃圾收集的MSDN的整个部分
因为Objects有时会在内存旁边保存资源.GC释放内存; IDisposable是这样你可以释放任何其他东西.