我有两个代码示例,我想知道它们之间有什么区别,哪个更好地用作最佳实践和性能:
using (TestForm test = new TestForm())
{
test.ShowDialog();
}
另一个是:
TestForm test = null;
try
{
test = new TestForm();
test.ShowDialog();
}
catch(Exception ex)
{
}
finally
{
test = null;
}
答案 0 :(得分:7)
IDisposable接口定义Dispose方法,以及使用“using”语法的可能性。可以实现类的dispose方法来释放资源,关闭数据库连接以及任何类型的最终化和清理。只是将类实例设置为null将不会执行dispose方法中定义的任何代码。作为一般规则,如果一个类实现了IDisposable,那么当你完成类实例时应该调用dispose。
答案 1 :(得分:4)
Dispose()
用于释放非托管资源。这个也可以在终结器中完成(可能会调用Dispose()
),但不要依赖它。如果没有完成,则泄漏非托管资源。
设置对null
的引用仅表示特定引用不再指向该对象。它可以在那之后存在很长一段时间(如果你有另一个引用,甚至可以无限期地存在 - 好吧,如果你有多个对Dispose()
d的对象的引用,那么它可能会很难看。
通常,当您完成Dispose()
时,请始终致电IDiposable
。如果将它们包装成using
语句,则更容易:
using (var foo = new SomeDiposableObject()) {
// do something with foo
}
答案 2 :(得分:-1)
IDisposable
模式是一种及时释放对象可能正在消耗的非托管和托管资源的机制。
模式的典型实现方式如下:
public void Dispose() //Implementes the IDisposable interface
{
this.Dispose(true);
GC.SupressFinalize(this); //All resources have been released, no need to run the finalizer. We make the GC's life a little easier;
}
protected void Dispose(bool disposing)
{
if (disposing)
{
//Relesase managed resources.
}
//Release unmanaged resources.
}
~MyDisposableObject() //finalizer
{
this.Dispose(false)
}
这里要注意的是,通过Dispose
方法释放资源与您在终结器中逻辑上预期的非常相似。由于两个主要原因,它不是直接在终结器中完成的:
终结器未按确定的顺序执行。这就是我们不从终结器(Dispose(false)
)处置托管资源的原因,因为对象持有的部分或全部托管资源可能已在对象本身之前完成。对于非托管资源,情况并非如此,因为根据定义,它们永远不会被GC
最终确定。
我们不知道何时运行终结器(它取决于GC
)。
基本思想是实现IDisposable
的对象是任何消费者都说的标志:“嘿,我正在坚持一定数量的非托管和/或托管资源,最终会当GC
决定我不再有用时发布,但如果你需要及时回复这些资源,请调用Dispose(),我很乐意帮忙。“。
另一方面,将引用变量设置为null
并不会释放任何资源。 如果您从对象中删除的引用是该对象的唯一引用,则该对象最终将由GC
收集,并且托管和非托管资源将被释放(何时,是任何人猜)。
如果有更多的实时引用仍然指向该对象,那么该对象将存在一个,并且不会释放任何资源。