【问题标题】:Can I expect that a stream is closed by the garbage Collector?我可以期望垃圾收集器关闭流吗?
【发布时间】:2011-01-11 16:18:11
【问题描述】:

我有一个类,比如带有“关闭”功能的流。此类的实例存储在字段/属性中。有时我必须用一个新的实例替换这个实例。不幸的是,我不知道是否有人仍在使用该对象的旧实例。(许多许多函数将此字段与多线程一起使用)。所以我可以在不关闭课程的情况下覆盖该字段。我可以期望 GC 删除未关闭的对象,或者我可以在 dispose 函数中将其关闭吗?

谢谢。

【问题讨论】:

    标签: .net vb.net stream


    【解决方案1】:

    你的类应该是implementingIDisposable,并且它的任何用户都应该在using statement中实例化它。

    这将确保正确关闭/处置。

    GC 不会关闭/处置仍被引用的类,因此这实际上取决于您编写的代码以及该类的使用方式。

    【讨论】:

    • OP 的类没有理由不能像 Stream 类那样也暴露 Close(),这最终会在所需的底层对象上调用 Dispose
    • @Aaron - 我同意它可以并且可能应该这样做,并且dispose 实现应该确保关闭。但是依赖代码的用户做正确的事情会导致有趣的错误。
    • 不幸的是,这就是 dispose 模式所需要的。除了让 GC 跟踪内存以外的非托管资源之外,没有办法保证非托管资源得到清理,除非让代码的用户采取特殊步骤(例如 using 语句)来保证清理。
    【解决方案2】:

    您不仅可以使用 dispose 方法关闭它,而且您必须关闭它,因为流最喜欢包含非托管资源,而垃圾收集器可以'不要照顾。如果你用完了Dispose 类,则始终实现IDisposable

    如果你在一个类中使用实现IDisposable的类,你的类也应该实现这个接口。

    【讨论】:

      【解决方案3】:

      FileStream 等。确实有一个 Finalize() 方法,它只调用Dispose()。虽然这确实可以保证句柄最终关闭,但它不是确定性的。如果您可以自己手动关闭流,那是非常受欢迎的方法。 Finalize() 方法仅在流未手动关闭的情况下才存在(通常是由于您的逻辑中的错误)。

      碰巧,即使Finalize() 方法也不能100% 保证被调用。但是,一旦您的程序退出,所有句柄都将被操作系统关闭。

      【讨论】:

        【解决方案4】:

        如果您的课程有终结器,那么可以。但是,根据您的描述,这不是重点。

        您很可能希望该类实现IDisposable,这样您就可以尽早释放非托管资源(或拥有的一次性实例)。

        但似乎存在更大的设计问题。鉴于您可以控制该字段,您应该知道何时可以安全地创建新实例和/或何时处置它。显然,您有一些跨线程的共享实例,但没有明确拥有该实例的东西。没有代码和更详细的描述,我可能错了,但这听起来像是一场等待发生的事故。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-11-18
          • 2012-11-04
          • 2013-08-10
          • 1970-01-01
          • 1970-01-01
          • 2011-05-27
          • 1970-01-01
          相关资源
          最近更新 更多