我有几个问题得不到正确的答案。
1)当我们没有析构函数时,为什么要在Dispose函数中调用SuppressFinalize?
2) Dispose和finalize用于在对象被垃圾回收之前释放资源。无论它是托管的还是非托管的资源,我们都需要释放它,那么为什么我们需要dispose函数内部的一个条件,当我们从IDisposable调用这个被覆盖的函数时,说pass 'true‘:Dispose,当从finalize调用时,传递false。
请看我从net复制的下面的代码。
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);
}
}如果我删除boolean protected Dispose函数并按如下方式实现会怎么样?
class Test : IDisposable
{
private bool isDisposed = false;
~Test()
{
Dispose();
}
public void Dispose()
{
// Code to dispose the managed resources of the class
// Code to dispose the un-managed resources of the class
isDisposed = true;
// Call this since we have a destructor . what if , if we don't have one
GC.SuppressFinalize(this);
}
} 发布于 2010-04-09 14:35:01
我这是在冒险,但是...大多数人不需要成熟的dispose模式。它被设计成在直接访问非托管资源(通常通过IntPtr)和面对继承时是可靠的。大多数情况下,这两者实际上都不是必需的。
如果您只是持有对实现IDisposable的其他东西的引用,那么几乎可以肯定的是,您不需要终结器-直接持有资源的任何东西都负责处理它。你可以用下面这样的东西来凑合:
public sealed class Foo : IDisposable
{
private bool disposed;
private FileStream stream;
// Other code
public void Dispose()
{
if (disposed)
{
return;
}
stream.Dispose();
disposed = true;
}
}请注意,这不是线程安全的,但这可能不是问题。
由于不必担心子类直接持有资源的可能性,您不需要抑制终结器(因为没有终结器)-您也不需要提供自定义处理的子类的方法。没有继承,生活变得更简单。
如果您确实需要允许非受控继承(即,您不愿意打赌子类将有非常特殊的需求),那么您需要使用完整的模式。
请注意,在.NET 2.0的SafeHandle中,您需要自己的终结器的情况甚至比在.NET 1.1中更少。
首先说明一下为什么会有一个disposing标志:如果你在终结器中运行,你引用的其他对象可能已经被终结了。你应该让他们自己清理,而且你应该只清理你直接拥有的资源。
发布于 2010-04-29 19:59:45
以下是主要事实
1)当你的类有一个终结器时,Object.Finalize就是它所覆盖的东西。TypeName()析构函数方法只是'override Finalize()‘等的简写
2)如果在终结化之前在Dispose方法中处理资源(例如,当从using块中出来时),则调用GC.SuppressFinalize。如果您没有终结器,则不需要执行此操作。如果你有一个终结器,这确保了对象从终结化队列中被移除(所以我们不会两次释放东西,因为终结器通常也会调用dispose方法)
3)你实现一个终结器作为一种“故障安全”机制。终结器保证会运行(只要CLR没有中止),所以它们允许你确保代码在Dispose方法没有被调用的情况下得到清理(也许程序员忘记在“using”块中创建实例等等)。
4)终结器是昂贵的,因为具有终结器的类型不能在Generation-0集合中被垃圾收集(最有效),并且通过在F-Reachable队列上引用它们来提升到Generation-1,因此它们表示GC根。直到GC执行第一代收集时,终结器才会被调用,资源才会被释放-所以只有在非常重要的情况下才实现终结器-并确保需要终结器的对象尽可能小-因为可终结化对象可以到达的所有对象也将被提升到第一代。
发布于 2010-04-09 14:24:36
保留第一个版本,它更安全,并且是dispose模式的正确实现。
SuppressFinalize告诉GC您已经完成了(类持有的)所有资源的销毁/处置,并且它不需要调用需要测试的destructor.参见Dispose MSDN文档(Dispose方法应该调用SuppressFinalize)。
https://stackoverflow.com/questions/2605412
复制相似问题