博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Finalize/Dispose资源清理模式
阅读量:6540 次
发布时间:2019-06-24

本文共 1715 字,大约阅读时间需要 5 分钟。

      由于最近在准备找工作,也从图书馆借了一本.net 程序员面试的“宝典”,本人一直也是不信什么程序员秘技、宝典,但是也不偏激,一本书至少是别人的经验的,多少还是能收益的。我也就利用零碎的时间常常翻阅看看的,看到关于析构函数和资源清理的时候,发现自己对里面的机制和原理不是很明白的,查阅一些资料后,写下自己的理解的。

    C#的析构函数

      与c++的析构函数不同,C#的析构函数并不在实例失效就调用。由于.net的垃圾回收机制,我们无法知道析构函数会在什么时候调用,而且我们也不能显式调用析构函数。我们只是知道,析构函数是在对象从托管的堆释放前的某个时刻调用。

     所以,如果你的代码包含珍贵的资源(非托管资源,如:数据库的连接,画笔,句柄),别在析构函数里处理,因为你根本不知道析构什么时候能运行的。所以,我们必须想一直我们可以控制的办法,让我们可以准确的控制资源的释放,现在Dispose 方法登场,帮助我们完全控制什么时候我们释放非托管资源。

     C#的析构函数与Finalize方法

    C#析构函数在编译后产生的中间IL代码,我们通过Ildasm的反汇编程序,我们可以看不到C#的析构函数,只是多了一个Finalize方法,这个就是析构函数在CLR中的本来模样。在对象变为不可访问的时候,将自动调用Finalize方法。

    Dispose方法代替Finalize方法的标准清理模式

     通过Dispose方法我们可以自己显示的释放非托管资源。像数据库连接这种很稀少的资源,能得到充分利用。Dispose方法必须首先实现IDisposable接口,代码如下:

   

public class MyClass : IDisposable    {        private bool disposed = false;        //Implement IDisposable.        public void Dispose()        {            Dispose(true);            GC.SuppressFinalize(this);//此处的调用,告诉垃圾回收器不要再调用析构函数        }        protected virtual void Dispose(bool disposing)        {            if (!disposed)            {                if (disposing)                {                    // 释放托管资源                }                //释放非托管资源                disposed = true;            }        }                ~MyClass()        {            Dispose(false);        }    }

    程序中的disposed作为标志位,为了防止在调用Dispse()方法后,析构函数调用时,再次释放资源。或者在有的时候,粗心的程序员在忘记调用Dispose()时,非托管资源在析构函数中也能得到释放。

  .NET框架里的标注清理模式

    在.net的框架中的很多的地方都应用到标准清理模式,如数据库连接的释放,文件、流的释放。

  

public   void Close()        {            Dispose();                }

  关于垃圾回收机制

     估计很多人会觉得我们需要关系垃圾回收机制吗?我觉得,应该了解一些机制的。我们在处理资源的时候,我们一般可以不关心垃圾回收机制,因为垃圾回收机制会帮我们优化内存回收。但是,涉及到非托管资源的时候,我们很关心时间的问题,此时我们如果能优化资源的利用问题的话,我们就提高很多程序的执行效率。

   

 

转载于:https://www.cnblogs.com/Johnnie/archive/2012/09/16/2687273.html

你可能感兴趣的文章
Apple Watch的非“智能手表”卖点
查看>>
单例模式(Singleton)
查看>>
函数指针和指针函数
查看>>
Python的函数参数传递:传值?引用?
查看>>
[转]分享2011年8个最新的jQuery Mobile在线教程
查看>>
android call require api level
查看>>
SQLSERVER是怎麽通过索引和统计信息来找到目标数据的(第一篇)
查看>>
Python版本切换和Pip安装
查看>>
SilverLigth学习笔记--控制 Silverlight控件样式(转)
查看>>
poj3262
查看>>
第四十天笔记
查看>>
4、动态代理
查看>>
Loj #6073.「2017 山东一轮集训 Day5」距离
查看>>
我的TCP/IP学习笔记
查看>>
shell--字符串的截取变量子串串
查看>>
轮毂电机光电增量编码器的ABZ信号详解
查看>>
TextBox Template
查看>>
Linux MySQL 储存中文失败简单解决办法
查看>>
洛谷——P1330 封锁阳光大学
查看>>
css选择器
查看>>