如果.NET有垃圾收集,那你为什么要显式调用IDisposable
?
答案 0 :(得分:48)
垃圾收集用于记忆。您需要处理非内存资源 - 文件句柄,套接字,GDI +句柄,数据库连接等。这通常是IDisposable
类型的基础,尽管实际句柄在引用链中可能相当长。例如,您可以Dispose
XmlWriter
处置StreamWriter
它有一个引用,它处理FileStream
它有一个引用,它会释放文件句柄本身。
答案 1 :(得分:8)
在其他评论上稍微扩展一下:
应该对所有引用了非托管资源的对象调用Dispose()方法。这样的示例包括文件流,数据库连接等。大多数时间工作的基本规则是:“如果.NET对象实现了IDisposable,那么在完成对象时应该调用Dispose()。
但是,还要记住其他一些事项:
除非绝对需要,否则不要在自己的对象中实现IDisposable。实施不当或不必要的实施实际上可以使事情变得更糟而不是更好。可以在这里找到一些很好的指导:
答案 2 :(得分:5)
因为对象有时会在内存旁边保留资源。 GC释放内存; IDisposable是你可以释放任何其他东西。
答案 3 :(得分:1)
因为您希望控制对象保留的资源何时清理。
请参阅,GC可以工作,但是当它感觉到时,它会这样做,即使这样,添加到对象的终结器也只能在2个GC集合之后被调用。有时,您希望立即清理这些对象。
这是使用IDisposable的时候。通过显式调用Dispose()(或使用using块的thr语法糖),您可以访问您的对象以标准方式清理自己(即您可以实现自己的cleanup()调用并显式调用它)
您希望立即清理的示例资源包括:数据库句柄,文件句柄,网络句柄。
答案 4 :(得分:1)
为了使用using关键字,对象必须实现IDisposable。 http://msdn.microsoft.com/en-us/library/yh598w02(VS.71).aspx
答案 5 :(得分:0)
IDisposable
界面通常用资源来描述,但大多数此类描述都未能真正考虑“资源”的真正含义。
有些对象需要要求外部实体代表他们做某事,而不利于其他实体,直到另行通知为止。例如,包含文件流的对象可能需要询问文件系统(可以是连接的Universe中的任何位置)以授予对文件的独占访问权。在许多情况下,对象对外部实体的需求将与外部代码对对象的需求联系在一起。一旦客户端代码完成了与上述文件流对象相关的所有操作,例如,该对象将不再需要对其关联文件进行独占访问(或任何访问)。
一般而言,要求实体做某事直到另行通知的对象X才有义务提交此类通知,但只要X的客户可能需要X的服务,就无法提供此类通知。 IDisposable
的目的是提供一种统一的方式让对象知道他们的服务将不再需要,以便他们可以通知代表他们的实体(如果有的话)他们的不再需要服务。调用IDisposable
的代码既不需要知道也不关心对象从外部实体请求的服务(如果有的话),因为IDisposable
仅仅邀请对象履行对外部实体的义务(如果有的话)。
为了根据“资源”来设置对象,当对象要求外部实体代表它做某事时(通常,但不一定,授予对某些东西的独占使用),直到另行通知,并释放资源,它告诉外部实体不再需要其服务。获取资源的代码不会产生“事物”,因为它承担了义务;释放资源不会放弃“事物”,而是履行义务。