下面的一次性图案怎么样?
using System;
public class MyClass : IDisposable
{
public void Dispose()
// Implement IDisposable
{
//just do the cleanup
GC.SuppressFinalize(this);
}
}
对不起,请注意。我想说,如果没有未管理的资源,我需要终结器吗?上述一次性图案不够好吗?是的,即使用户/开发者没有调用dispose,默认情况下GC不会调用处理吗?
那么GC调用dispose和终结器的顺序呢?
另外,当我们有终结器时,为什么我们调用Dispose with false作为参数。
来自http://msdn.microsoft.com/en-us/magazine/cc163392.aspx#S2,看起来总是建议从终结器而不是托管引用中释放未损坏的资源。
始终建议从Dispose方法中释放未损坏的资源......
尽管如此,仍然没有得到全部要点并阅读文章。
using System;
public class MyClass : IDisposable
{
private bool disposed = false;
protected virtual void Dispose(bool suppressFinalize)
{
if (!disposed)
{
//Just do the cleanup
//and release resources
disposed = true;
}
if (!suppressFinalize)
{
GC.SuppressFinalize(this);
}
}
public void Dispose()
// Implement IDisposable
{
Dispose(true);
}
~MyClass() // the finalizer
{
Dispose(false);
}
}
的问候, 梦
答案 0 :(得分:11)
因为您可能指向对非托管资源(例如Windows句柄)的引用,并且即使没有人调用Dispose
,您也希望释放它们。
这是非常罕见的 - 通常你只有真的通过其他托管类型间接引用非托管资源,如果需要它们将有终结器。
答案 1 :(得分:4)
.Net中的终结+ IDisposable
实际上是两个不同的问题,试图通过单一的一次性模式来解决。
非托管资源是不受CLR和垃圾收集器控制的项目。文件句柄,从PInvoke返回的内存等项目......如果这些资源没有被用户代码明确释放,它们将泄漏并在剩余的进程生命周期中出现。他们被释放至关重要。
这是终结器的用武之地。它将在CLR收集之前在对象上运行。这不需要消费者遵循一次性模式,因此是确保释放非托管资源以防止泄漏的良好后备。
如果您的代码不包含任何直接保存的非托管资源,则没有理由拥有终结器。代码的责任是使非托管资源拥有终结器。