浅谈C#托管程序中的资源释放问题
来源:互联网 发布:知是心之体,心自然会知 编辑:程序博客网 时间:2024/05/16 06:13
///<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程序块 确定,在显示调用时 那么在定义一个类型的时候,是否一定要给出这三个函数地实现呢。我的建议大致如下。<!--[if !supportLists]-->1.<!--[endif]-->提供析构函数,避免资源未被释放,主要是指非内存资源;<!--[if !supportLists]-->2.<!--[endif]-->对于Dispose和Close方法来说,需要看所定义的类型所使用的资源(参看前面所说),而决定是否去定义这两个函数;<!--[if !supportLists]-->3.<!--[endif]-->在实现Dispose方法的时候,一定要加上“GC.SuppressFinalize( this )”语句,避免再让GC调用对象的析构函数。C#程序所使用的内存是受托管的,但不意味着滥用,好地编程习惯有利于提高代码的质量以及程序的运行效率。Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1023352- 浅谈C#托管程序中的资源释放问题
- 浅谈C#托管程序中的资源释放问题
- 浅谈C#托管程序中的资源释放问题
- 浅谈C#托管程序中的资源释放问题
- 浅谈C#托管程序中的资源释放问题 来源:愚翁
- 浅谈C#托管程序中的资源释放问题
- 浅谈C#托管程序中的资源释放问题 好文章!!!
- [转载]浅谈C#托管程序中的资源释放问题
- 浅谈C#托管程序中的资源释放问题 好文章!!!
- 浅谈C#托管程序中的资源释放问题
- 浅谈C#托管程序中的资源释放问题
- 浅谈C#托管程序中的资源释放问题(ZT)
- 浅谈C#托管程序中的资源释放问题
- 浅谈C#托管程序中的资源释放问题
- 浅谈C#托管程序中的资源释放问题
- 浅谈C#托管程序中的资源释放问题
- 浅谈C#托管程序中的资源释放问题
- 浅谈C#托管程序中的资源释放问题
- 提取HTML代码中文字的C#函数
- ASP编写完整的一个IP所在地搜索类
- js中取frameset值的问题??谢谢各位老鸟?
- 第三章学习笔记
- 取得AspxGridview中某控件的值(适用RadioButton ,CheckBox)以及在AspGridView取得某一行的方法
- 浅谈C#托管程序中的资源释放问题
- ASP编写完整的一个IP所在地搜索类
- C#的关键字 [STAThread]
- 第一个项目管理
- vbs类生成xml文件
- 补丁升级系统流程
- 基于Asterisk的VoIP开发指南——Asterisk 模块编写指南(1)
- 毕业到现在终于把CSDN注册到了!!!!
- 我的csdn排名和浏览量半个月没有变化