【发布时间】:2016-04-14 20:27:32
【问题描述】:
我读过一些关于 GC、Finalizers、Managed & Unmanaged Objects、Disposable pattern @StackOverflow 的文章。
目前,我对正确使用 GC、终结器、一次性模式和托管、非托管资源术语感到很困惑。
恕我直言,关于上述主题有很多误导性的答案。
例如;
我以this的帖子为例
这个问题的公认答案意味着,如果我们不调用默认实现 IDisposable 接口的 .net 对象的 dispose 方法,我们将无法释放非托管资源。
我认为这是一个错误的说法。首先在托管资源和非托管资源之间存在概念混淆。在我看来,
托管资源:任何实现 IDisposable 接口的 .NET 类,例如 Streams 和 DbConnections。
非托管资源:封装在托管资源类中的填充物。 Windows 句柄是最简单的例子。
正如@kicsit 在this 帖子中所说的那样
所以我最终知道所有默认实现 IDisposable 接口的类(例如 pen、streamwriter)都是托管资源 包括非托管资源。
显式调用 IDispose 方法和让 GC 执行的所有区别在于,一个间接地向 GC 发出信号,表明可以在下一次 GC 期间清理对象,后者是完全不确定的。
但是,当我查看 Dataset 和 Datatable 类时,尽管它们默认实现 IDisposable,但它们内部不拥有任何非托管资源。 This接受的答案也支持我的想法。
引自回答
system.data 命名空间 (ADONET) 不包含非托管资源。 因此,只要您没有为自己添加一些特殊的东西,就不需要处理任何这些。
所以我的第一个想法失败了。默认情况下拥有 Disposable 并不一定意味着类/对象内部有非托管资源。
Q1)是真的吗?
Q2) 如果我使用像 streamwriter 这样默认包含 IDisposable 接口的类而不调用它。GC 会将其放入 Finalization 队列然后分别调用 Dispose 方法吗?(我的意思是 StreamWriter.Dispose() 方法是相当于 StreamWriter.Close()
Q3) 如果我们显式实现析构函数,是否会出现终结队列?
【问题讨论】:
标签: c# garbage-collection dispose idisposable finalizer