在this answer我找到了,
清理Finalize方法中的非托管资源 Dispose方法中的托管方法,当Dispose / Finalize模式时 已在您的代码中使用。
后来我发现this nice article关于敲定和处理并清楚地了解它们。本文包含以下代码(第3页),以解释这些概念:
class Test : IDisposable
{
private bool isDisposed = false;
~Test()
{
Dispose(false);
}
protected void Dispose(bool disposing)
{
if (disposing)
{
// Code to dispose the managed resources of the class
}
// Code to dispose the un-managed resources of the class
isDisposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
但在此之下,会出现相同的注释(我在此问题的开头包含该注释)。
Dispose / Finalize Pattern Microsoft建议您在使用非托管资源时实施Dispose和Finalize。那么正确的顺序就是 是供开发人员调用Dispose。 Finalize实施会 运行,当对象出现时,资源仍将被释放 即使开发人员忽略了调用Dispose,也会收集垃圾 方法明确。 Francesco Balena在他的博客中写道: 只有在类型调用时才应使用Dispose / Finalize模式 分配非托管资源的非托管代码(包括非托管资源) 内存)并返回一个必须最终用于释放的句柄 资源。处置和最终确定必须链接到他们的父母 对象通过调用父对象的方法后调用它们 处理或完成自己的成员“。 简单地说,清理Finalize方法中的非托管资源和Dispose方法中的托管资源, Dispose / Finalize模式已在您的代码中使用。
现在我又困惑了。在整篇文章和代码示例中,显示应在Dispose()
中释放非托管资源。但那个评论的相关性是什么?
修改
确认这一行:
简单地说,清理Finalize方法中的非托管资源 Dispose方法中的托管方法,当Dispose / Finalize时 模式已在您的代码中使用
是错误的,我编辑了this answer。
答案 0 :(得分:36)
看得很简单。
Dispose
和 Finalize
。开发人员会调用Dispose
,以便在资源不再需要时立即释放资源。如果他们忘记调用Dispose
,那么Framework会在自己的GC循环中调用finalize(通常会花费自己的甜蜜时间)。Finalize
或Dispose
。Dispose()
并且您没有'的类型的任何对象的引用,则实现Dispose()
已经处理好了。一些经典的例子:
System.IO.FileStream
对象管理文件的锁/流句柄。所以它实现了dispose和finalize。如果开发人员处理它,那么另一个程序可以立即访问它。如果他忘记处理它,那么Framework会最终确定它并在GC循环中关闭句柄。
System.Text.StringBuilder
没有任何非托管资源。所以没有处理完毕。
就模式而言,
意味着什么// Code to dispose the managed resources of the class
调用您拥有的任何.NET对象的Dispose方法作为该类中的组件
并且
// Code to dispose the un-managed resources of the class
意味着关闭原始句柄和指针。这是您的更新代码以及示例
class Test : IDisposable
{
private bool isDisposed = false;
~Test()
{
Dispose(false);
}
protected void Dispose(bool disposing)
{
if (disposing)
{
// Code to dispose the managed resources of the class
internalComponent1.Dispose();
internalComponent2.Dispose();
}
// Code to dispose the un-managed resources of the class
CloseHandle(handle);
handle = IntPtr.Zero;
isDisposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
答案 1 :(得分:3)
如果Foo
的资源可以从确定性清理中受益,但没有一个可以在终结器中清除,则应该实现IDisposable
但不应覆盖Finalize
或者析构函数。如果一个类拥有多个资源,并且至少有一个资源可以在终结器中清理,那么可以在终结器中清理的每个离散资源都应该封装到自己的Finalizer /析构函数对象中(可以在protected嵌套类),包含这些资源的类应该包含对包装器对象的引用。完成后,外部类将适合具有Dispose
方法但没有终结器/析构函数的类的模式。