【发布时间】:2011-01-11 16:18:11
【问题描述】:
我有一个类,比如带有“关闭”功能的流。此类的实例存储在字段/属性中。有时我必须用一个新的实例替换这个实例。不幸的是,我不知道是否有人仍在使用该对象的旧实例。(许多许多函数将此字段与多线程一起使用)。所以我可以在不关闭课程的情况下覆盖该字段。我可以期望 GC 删除未关闭的对象,或者我可以在 dispose 函数中将其关闭吗?
谢谢。
【问题讨论】:
我有一个类,比如带有“关闭”功能的流。此类的实例存储在字段/属性中。有时我必须用一个新的实例替换这个实例。不幸的是,我不知道是否有人仍在使用该对象的旧实例。(许多许多函数将此字段与多线程一起使用)。所以我可以在不关闭课程的情况下覆盖该字段。我可以期望 GC 删除未关闭的对象,或者我可以在 dispose 函数中将其关闭吗?
谢谢。
【问题讨论】:
你的类应该是implementingIDisposable,并且它的任何用户都应该在using statement中实例化它。
这将确保正确关闭/处置。
GC 不会关闭/处置仍被引用的类,因此这实际上取决于您编写的代码以及该类的使用方式。
【讨论】:
dispose 实现应该确保关闭。但是依赖代码的用户做正确的事情会导致有趣的错误。
using 语句)来保证清理。
您不仅可以使用 dispose 方法关闭它,而且您必须关闭它,因为流最喜欢包含非托管资源,而垃圾收集器可以'不要照顾。如果你用完了Dispose 类,则始终实现IDisposable。
如果你在一个类中使用实现IDisposable的类,你的类也应该实现这个接口。
【讨论】:
FileStream 等。确实有一个 Finalize() 方法,它只调用Dispose()。虽然这确实可以保证句柄最终关闭,但它不是确定性的。如果您可以自己手动关闭流,那是非常受欢迎的方法。 Finalize() 方法仅在流未手动关闭的情况下才存在(通常是由于您的逻辑中的错误)。
碰巧,即使Finalize() 方法也不能100% 保证被调用。但是,一旦您的程序退出,所有句柄都将被操作系统关闭。
【讨论】:
如果您的课程有终结器,那么可以。但是,根据您的描述,这不是重点。
您很可能希望该类实现IDisposable,这样您就可以尽早释放非托管资源(或拥有的一次性实例)。
但似乎存在更大的设计问题。鉴于您可以控制该字段,您应该知道何时可以安全地创建新实例和/或何时处置它。显然,您有一些跨线程的共享实例,但没有明确拥有该实例的东西。没有代码和更详细的描述,我可能错了,但这听起来像是一场等待发生的事故。
【讨论】: