///<summary>
/// The class to show three disposal function
///</summary>
public class DisposeClass:IDisposable
{
public void Close()
{
Debug.WriteLine( "Close called!" );
}
~DisposeClass()
{
Debug.WriteLine( "Destructor called!" );
}
#region IDisposable Members
public void Dispose()
{
// TODO: Add DisposeClass.Dispose implementation
Debug.WriteLine( "Dispose called!" );
}
#endregion
}
对于Close来说不属于真正意义上的释放,除了注意它需要显示被调用外,我在此对它不多说了。而对于析构函数而言,不是在对象离开作用域后立刻被执行,只有在关闭进程或者调用GC.Collect方法的时候才被调用,参看如下的代码运行结果。private void Create()
{
DisposeClass myClass = new DisposeClass();
}
private void CallGC()
{
GC.Collect();
}
// Show destructor
Create();
Debug.WriteLine( "After created!" );
CallGC();
运行的结果为:After created!
Destructor called! 显然在出了Create函数外,myClass对象的析构函数没有被立刻调用,而是等显示调用GC.Collect才被调用。 对于Dispose来说,也需要显示的调用,但是对于继承了IDisposable的类型对象可以使用using这个关键字,这样对象的Dispose方法在出了using范围后会被自动调用。例如:using( DisposeClass myClass = new DisposeClass() )
{
//other operation here
}
如上运行的结果如下: Dispose called! 那么对于如上DisposeClass类型的Dispose实现来说,事实上GC还需要调用对象的析构函数,按照前面的GC流程来说,GC对于需要调用析构函数的对象来说,至少经过两个步骤,即首先调用对象的析构函数,其次回收内存。也就是说,按照上面所写的Dispose函数,虽说被执行了,但是GC还是需要执行析构函数,那么一个完整的Dispose函数,应该通过调用GC.SuppressFinalize(this )来告诉GC,让它不用再调用对象的析构函数中。那么改写后的DisposeClass如下:///<summary>
/// The class to show three disposal function
///</summary>
public class DisposeClass:IDisposable
{
public void Close()
{
Debug.WriteLine( "Close called!" );
}
~DisposeClass()
{
Debug.WriteLine( "Destructor called!" );
}
#region IDisposable Members
public void Dispose()
{
// TODO: Add DisposeClass.Dispose implementation
Debug.WriteLine( "Dispose called!" );
GC.SuppressFinalize( this );
}
#endregion
}
通过如下的代码进行测试。private void Run()
{
using( DisposeClass myClass = new DisposeClass() )
{
//other operation here
}
}
private void CallGC()
{
GC.Collect();
}
// Show destructor
Run();
Debug.WriteLine( "After Run!" );
CallGC();
运行的结果如下:Dispose called!
After Run!
显然对象的析构函数没有被调用。通过如上的实验以及文字说明,大家会得到如下的一个对比表格。|
析构函数 |
Dispose方法 |
Close方法 | |
|
意义 | 销毁对象 | 销毁对象 | 关闭对象资源 |
|
调用方式 | 不能被显示调用,会被GC调用 | 需要显示调用 或者通过using语句 | 需要显示调用 |
|
调用时机 | 不确定 | 确定,在显示调用或者离开using程序块 | 确定,在显示调用时 |
本文介绍了C#中的资源管理概念,包括托管与非托管资源的区别,GC的工作原理及资源释放方式。详细探讨了析构函数、Dispose方法及Close方法的使用场景与实现细节。
&spm=1001.2101.3001.5002&articleId=3547314&d=1&t=3&u=a5f8b75f8f5c4268955a6658f86062e3)
1685

被折叠的 条评论
为什么被折叠?



