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

IDisposable接口

c#
  •  12
  • TalentTuner  · 技术社区  · 15 年前

    IDisposable 接口和它在.net中的使用,但在我看来,如果我正在编写所有托管代码,那么 IDisposable公司 接口有意义吗?

    我知道何时以及如何使用Idisposible,但我的问题是,如果我正在编写所有托管代码,那么说一个简单的类在其中并不昂贵,因此如果我实现 在这个类中,做一些清理,比如释放一些全局值,这有意义吗?

    6 回复  |  直到 15 年前
        1
  •  11
  •   Nayan    15 年前

    不,您可能不需要使用IDisposble接口。不过,在某些情况下建议(我可能会在稍后的记忆中添加更多内容:):

    1. 你打开了一些流,这些流在类的对象死之前一直是活动的。即使这些文件/网络等的实现是受管理的,但它们在Win32模式下深入到句柄。因此,你有机会写一篇 Dispose

    2. 感谢supercat:您的类实现了许多事件处理程序并将它们与事件挂钩。公开事件的类的对象,如 Form 等等,不会被GC释放,因为类的本地实现(可能)仍然连接到这些事件中。你可以在

    隐马尔可夫模型。。。我现在想不起来了,但是如果类的行为很复杂,您可能需要重新考虑为什么不希望实现 IDisposable 接口。

        2
  •  7
  •   Steve Michelotti    15 年前

    经验法则:如果类型的成员变量本身是IDisposable的,或者类型是非托管的,则需要实现IDisposable。GC在.NET中是不确定的,IDisposable为您提供了一种确定的方法,不是回收内存而是回收 资源 . 因此,当Dispose()被调用时,GC不会立即释放内存,但可以清理非托管内存

        3
  •  3
  •   Shay Erlichmen    15 年前

        4
  •  3
  •   supercat    15 年前

    一个很少提及的场景,其中正确使用iDisposable是 批评的 是一个使用寿命短的对象,它接收来自长寿命对象的事件。此类对象的Dispose方法必须取消订阅其事件。如果对象本身没有取消订阅,它将不符合垃圾回收的条件,直到其订阅的事件的对象符合垃圾回收的条件;这很可能永远不会。

    例如,某些类型的枚举器需要订阅“object changed”消息。在一个长时间运行的程序的执行过程中创建数千个这样的枚举器是完全合理的。如果这些枚举数没有被取消订阅,它们可能会有效地阻塞系统,即使它们从未使用托管内存以外的任何资源。

    请注意,顺便说一下,尽管处理这样一个对象很重要,但是添加终结器来确保这样的处理是无用的。如果事件发布者超出了范围,尝试从其某个事件中取消订阅充其量是无用的,而且可能是危险的。由于事件订阅服务器不能超出作用域,除非它接收到的所有事件的发布服务器也超出了作用域,所以只有在没有其他事情可做时才会调用终结器。

        5
  •  2
  •   stakx - no longer contributing Saravana Kumar    15 年前

    是的,即使你身边没有任何托管资源, IDisposable 还是有帮助的。为什么?因为你可以使用 Dispose 方法将对象引用重置回 null .

    注意,这本身还不能释放任何资源,因为垃圾收集是不确定的(即,它通常不会在您选择的任何时刻运行),但它会断开对象之间的引用(链接),使某些对象更有可能在下次运行GC时获得垃圾收集。

        6
  •  0
  •   jeffo    15 年前

    不,只有在制作成本很高的情况下,才可以一次性使用。