学习C#时,经常会遇到C#执行Finalize方法问题,这里将介绍C#执行Finalize方法问题的解决方法。
C#执行Finalize方法
几乎可以完全肯定地说,对于大多数C++编程人员而言,C#与C++***的不同之处就在于碎片收集。这也意味着编程人员再也无需担心内存泄露和确保删除所有没有用的指针。但我们再也无法精确地控制杀死无用的对象这个过程。事实上,在C#中没有明确的destructor。
如果使用非可管理性资源,在不使用这些资源后,必须明确地释放它。对资源的隐性控制是由Finalize方法(也被称为Finalize)提供的,当对象被销毁时,它就会被碎片收集程序调用收回对象所占用的资源。
Finalize应该只释放被销毁对象占用的非可管理性资源,而不应牵涉到其他对象。如果在程序中只使用了可管理性资源,那就无需也不应当C#执行Finalize方法,只有在非可管理性资源的处理中才会用到Finalize方法。由于Finalize需要占用一定的资源,因此应当只在需要它的方法中执行Finalize。
直接调用一个对象的Finalize方法是绝对不允许的(除非是在子类的Finalize中调用基础类的Finalize。),碎片收集程序会自动地调用Finalize。
从语法上看,C#中的destructor与C++非常相似,但其实它们是完全不同的。C#中的destructor只是定义Finalize方法的捷径。因此,下面的二段代码是有区别的:
- MyClass()
- {
- // 需要完成的任务
- }
- MyClass.Finalize()
- {
- // 需要完成的任务
- base.Finalize();
- }
Finalize和Dispose使用谁?
从上面的论述中我们已经很清楚,显性地调用Finalize是不允许的,它只能被碎片收集程序调用。如果希望尽快地释放一些不再使用的数量有限的非可管理性资源(如文件句柄),则应该使用IDisposable界面,这一界面有个Dispose方法,它能够帮你完成这个任务。Dispose是无需等待Finalize被调用而能够释放非可管理性资源的方法。
如果已经使用了Dispose方法,则应当阻止碎片收集程序再对相应的C#执行Finalize方法。为此,需要调用静态方法GC.SuppressFinalize,并将相应对象的指针传递给它作为参数,Finalize方法就能调用Dispose方法了。据此,我们能够得到如下的代码:
- public void Dispose()
- {
- // 完成清理操作
- // 通知GC不要再调用Finalize方法
- GC.SuppressFinalize(this);
- }
- public override void Finalize()
- {
- Dispose();
- base.Finalize();
- }
【编辑推荐】