问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

C# dispose怎么用

发布网友 发布时间:2022-07-30 00:56

我来回答

1个回答

热心网友 时间:2023-07-18 23:01

一:什么是资源
在开始本文前,需要一些准备知识。首先要提出“什么是资源”。在CLR出来之后,Windows系统资源开始分为“非托管资源”和“托管资源”。
非托管资源是指:所有的Window内核对象(句柄)都是非托管资源,如对于Stream,数据库连接,GDI+的相关对象,还有Com对象等等,这些资源并不是受到CLR管理;
托管资源是指:由CLR管理分配和释放的资源,即由CLR里new出来的对象。
其次再来讲,资源的释放方式。
非托管资源:需要显式释放的,也即需要你写代码释放;
托管资源:并不需要显式释放,但是如果引用类型本身含有非托管资源,则需要进行现实释放;
二:显式释放的C#实现
显式释放的C#实现,由C#语法支持的有:
1:实现IDisposable接口的Dispose方法;
2:析构方法(终结器);
不由C#语法支持,但是约定支持的显式释放是:
3:提供显示释放方法,比如常用的Close方法;
三:Dispose、Close和析构方法异同点
但是,还需要区分这3种方式的异同点。首先,你无法调用析构方法。析构方法是由垃圾回收机制进行调用的。换句话来说,就是你不知道析构方法被调用的时机。严格意义上来说,它只是作为资源释放的一个补救措施。
资源释放的一个正确的措施是为类型实现IDisposable接口的Dispose。当你需要释放类型的资源的时候,应该显示的调用Dipose方法。当然,这里还有一个C#的语法糖,就是使用using程序块,在离开using程序块的时候,CLR会自动调用类型所创建对象的Dipose方法。
可能有人会问道,既然可以通过Dispose方法的方式来进行资源的释放,为什么有些类型还需要提供一个Close方法。这里面的区别,或者说约定在于,如果你仔细观察这些类型:他们基本都只公开了Close方法,他们都实现了IDisposable,但都隐藏了Dispose方法。以Socket这个类为例,它:
1:提供public void Close()
public void Close()
{
//….
((IDisposable)this).Dispose();
//….
}
2:提供显式void IDisposable.Dispose()
void IDisposable.Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
3:提供protected virtual void Dispose(bool disposing)。真正的资源释放的代码放在这里。
所以理论上来将,提供Close方法最终还是使用的Dispose方法,之所以这么做,是因为这些类型出于显式实现IDisposable的因素,在调用这些Dispose方法的时候,必须完成一次转型,如:
((IDisposable)new A()).Dispose();
为了避免转型,同时也为了避免不熟悉C#语法的开发人员更直观的释放资源,提供了Close方法。
在上文的例子中,你可能已经注意到IDisposable.Dispose这个方法中,包含一句:
GC.SuppressFinalize(this);
这是告诉CLR,在进行垃圾回收的时候,不用再继续调用析构方法(终结器)了。是的,因为你已经手动释放资源了。这也从另一个方面验证了析构方法只是作为资源释放的补救机制。因为假设你忘记Close或者Dispose了,CLR会在垃圾回收的时候为你做这件事。查看Socket的析构函数,你会很好的理解这一点。
~Socket()
{
this.Dispose(false);
}
是的,析构方法调用的也是Dispose。
备注1:本文带来几个争论
1:托管资源本身是否需要显式释放。答案显然是:不需要;
2:如果引用类型对象不再需要,是否需要显式=null;答案是:即使不这样做,GC也会进行垃圾回收。
3:将托管资源分为引用类型资源和值类型资源这种分类方法是有问题的,或者说是错误的。正确的分类法应该是栈资源和堆资源。线程栈中存放的是方法的实参和方法内部的局部变量。堆上存放的是类型对象本身及对象的两个额外成员:类型对象指针和同步块索引。
4:Dispose方法本身是用来让你放置资源清理代码的。显然,一个空方法并不代表清理工作本身,真正执行清理工作的是你具体的代码。
备注2:推荐Dipose模式实现
如:基类
代码
class ClassShouldDisposeBase : IDisposable
{
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (disposing)
{
//执行基本的清理代码
}
}

~ClassShouldDisposeBase()
{
this.Dispose(false);
}

}
子类:
代码
class ClassShouldDispose: ClassShouldDisposeBase
{
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// 执行子类清理代码
// 如有必要,执行base.Dispose(disposing);
}
else
{
// 如有必要,执行base.Dispose(disposing);
}
}

public void Close()
{
//调用本类或者基类的Dispose方法
//其它代码
}
}
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
苹果手机微信怎么换漂亮字体(苹果手机微信怎么换行输入) 有什么好用的app转换字体 手写转文字的软件 erp可以看评论地址吗 淘宝评论url是什么意思? 揭秘:码牌支付风控升级,背后真相揭秘 电脑电视直播软件哪个好用什么软件好电脑看电视直播 潼南子同街学区是哪些 三极管BU406价格和参数? 火锅料放在冰柜忘了插电一个星期给会坏了吗 火锅的设备有哪些 高一复合函数概念 SAT数学题 Function f is defined by f(x)=(x-a)(x-b)/(x-c), where... 宣化上人答:念经有什么好处 雇佣童工处罚有哪些? arc数学中的arc是什么 2022最火闺蜜网名英文,2020年最火的闺蜜网名三人英文 2022最火的闺蜜网名 2022最火的闺蜜网名有哪些 非法雇佣童工怎么处罚 用人单位非法招用童工的由劳动行政部门处以什么处罚 女士简单又大气的敬酒话顺风又顺水 适合女士的祝酒词 对雇用童工是如何处罚的? 用人单位非法招用童工要如何处罚 20岁女孩月经量多且时间长吃什么药好 非法使用童工怎么处罚 听说,用过的床单不能再用做窗帘,这是真的么?为什么,有什么说法? 跪求 高中函数视频 哪里有 使用童工处罚的标准是什么 汨汨是啥意思??、 非法雇佣童工应该处罚多少钱 网络词汇"玻璃"什么意思 什么是消费函数?中国的消费需求不足的因素有哪些 消费函数 是每一年的不一样吗? 衣服上的油味怎么去除 衣服上的油味去除方法 凯恩斯的消费函数的介绍 请问谁有马上花链接入口,收到信息说我今天到期,但是我印象中好像没有... 2岁小孩不吃饭是什么原因 老鼠怕什么声音灭鼠,猫叫声驱鼠时长20分钟完整版 老鼠怕什么声音灭鼠 关于老鼠怕什么声音介绍 哪些食物会让宝宝过敏?宝宝过敏该如何护理? 八个月宝宝对鱼虾蛋过敏,那么该如何补充营养? 蕨菜怎么处理不粘 吃蕨菜禁忌 吃蕨菜需要注意如下事项 新鲜蕨菜怎么处理才能吃 想开家海参店拜请各位大虾给起个响亮好听的名字 东汉末年的名医张仲景被称为什么 想让自己变白,我该用什么办法? 海南琼海旅游攻略推荐一下呗? 琼海旅游 琼海旅游攻略