C# IDisposable的理解
C#里可以嵌入非托管代码,这就涉及到了这些代码资源的释放。以前总是看到别人的代码里那么写,也没有好好想想为什么,今天看了书,总结一下。
资源释放分为两种:
- 托管的
- 非托管的
两者的释放方式不一致:
- 没有非托管资源的,GC在运行时,会自动回收和释放;
- 含有非托管资源的,必须提供一个析构器,他们也会在内存里停留的时间会更长,最终被加入一个叫做finalization queue的结构,然后由GC在另一个线程释放;
实现IDispose接口是一种标准的释放资源的方式,正确使用会减少很多的bug和因为资源释放而引起的问题。正如上面所说,包含了非托管资源的代码,是必须提供一个析构器的。这样做的目的,是为了保证类的使用者,即使没有显式地调用Dispose方法,也可以正确地释放资源。
生产环境中的代码里,会有很多的继承,因此为了保证子类在调用时能够正确地执行父类的资源释放,在标准模式中,将真正的资源释放方法Dispose方法,抽象为一个virtual的方法,由子类去override,并在其中调用base的Dispose方法。
释放资源的Dispose方法,应该完成以下几件事(引用Effective C#)
- 释放所有的非托管资源;
- 释放所有的托管资源;
- 设定一个标志,标志资源是否已经销毁;对于销毁的对象,仍旧调用,则应抛异常;
- 跳过终结操作,调用GC.SuppressFinalize(this)方法。
以上,文字内容结束,基本的代码如下:
using System;
using System.Diagnostics; namespace Learn
{
class Program
{
private static int Cnt = ; static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = ; i < Cnt; i++)
{
IDisposeDerived de = new IDisposeDerived();
}
sw.Stop();
Console.WriteLine("total time is: " + sw.ElapsedMilliseconds);
Console.ReadLine();
}
} internal class IDisposeBase : IDisposable
{
// never add this unless unmanaged resources exist
// cauz this will add extra burdon and make negative influence on performance
//~IDisposeBase()
//{
// Dispose(false);
//} private bool AlreadyDisposed = false; public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} protected virtual void Dispose(bool shouldDisposeManagedReources)
{
if (AlreadyDisposed)
return;
if (shouldDisposeManagedReources)
{
// dispose the managed resources
// release the events
// etc.
}
// dispose the unmanaged resources // set the flag
AlreadyDisposed = true;
} public void MethodForPublic()
{
if (AlreadyDisposed)
throw new Exception("object has been disposed!");
// do the normal things
}
} internal class IDisposeDerived : IDisposeBase
{
//~IDisposeDerived()
//{
// Dispose(false);
//} private bool AlreadyDisposed = false; protected override void Dispose(bool shouldDisposeManagedReources)
{
if (AlreadyDisposed)
return;
if (shouldDisposeManagedReources)
{
// dispose managed resources
}
// dispose unmanaged resources // call the base's dispose method
base.Dispose(shouldDisposeManagedReources); // set the flag
AlreadyDisposed = true;
}
}
}
代码里增加了包含析构器的实现,可以对比一下,性能差异十分明显。
无析构器的实现结果:

有析构器的实现结果:

C# IDisposable的理解的更多相关文章
- C#中对IDisposable接口的理解
http://blog.sina.com.cn/s/blog_8abeac5b01019u19.html C#中对IDisposable接口的理解 本人最近接触一个项目,在这个项目里面看到很多类实现了 ...
- 深入理解C#中的IDisposable接口
写在前面 在开始之前,我们需要明确什么是C#(或者说.NET)中的资源,打码的时候我们经常说释放资源,那么到底什么是资源,简单来讲,C#中的每一种类型都是一种资源,而资源又分为托管资源和非托管资源,那 ...
- 【转】C#中对IDisposable接口的理解
IDisposable接口定义:定义一种释放分配的资源的方法. .NET 平台在内存管理方面提供了GC(Garbage Collection),负责自动释放托管资源和内存回收的工作,但它无法对非托管资 ...
- 深入理解C#中的IDisposable接口(转)
转自:https://www.cnblogs.com/wyt007/p/9304564.html 写在前面 在开始之前,我们需要明确什么是C#(或者说.NET)中的资源,打码的时候我们经常说释放资源, ...
- C# ~ 由 IDisposable 到 GC
IDisposable 接口 1. 托管资源和非托管资源 · 托管资源 a. CLR 控制和管理的内存资源,如程序中在 Heap 上分配的对象.作用域内的变量等: b. GC 机制实现自 ...
- MVC+EF 理解和实现仓储模式和工作单元模式
MVC+EF 理解和实现仓储模式和工作单元模式 原文:Understanding Repository and Unit of Work Pattern and Implementing Generi ...
- OWIN的理解和实践(二) – Host和Server的开发
对于开发人员来说,代码就是最好的文档,如上一篇博文所说,下面我们就会基于Kanata项目的一些具体调用代码,来进一步深入理解OWIN的实现和作用. 今天我们先针对Host和Server来实现一个简单的 ...
- 【转向Javascript系列】深入理解Generators
随着Javascript语言的发展,ES6规范为我们带来了许多新的内容,其中生成器Generators是一项重要的特性.利用这一特性,我们可以简化迭代器的创建,更加令人兴奋的,是Generators允 ...
- 【EntityFramework 6.1.3】个人理解与问题记录
前言 又是一个炎热夏日的晚上,开着空调听着音乐又开始了我们今天的博文.此文并不是ROM工具哪家强之类的引战贴,只是本文自己的一点看法和见解,望前辈看官有望斧正 声明 本文欢迎转载,原文地址:http: ...
随机推荐
- jquery上传控件uploadify使用备忘
我简单修改了js和样式,效果如下 使用起来也是超简单,将文件下载并解压到你网站目录下,然后 .在使用位置插入代码 ============================= <iframe wi ...
- WebForms vs. MVC
[译]WebForms vs. MVC(推荐阅读) 正文如下======================================================= 原文示例(VS2012): ...
- 调用MobileAPI的设计(iOS篇)
调用MobileAPI的设计(iOS篇) 这一节讲如何发起网络请求. iOS用于调用MobileAPI的第三方组件很多,我们这里采用的是以下组件: 1)ASIHTTPRequest,用于请求Mobil ...
- JavaScript怎么上传图片
JavaScript怎么上传图片 在XMLHttpRequest Level2出台之前,大多数的异步上传图片都是利用iframe去实现的. 至于具体的实现细节,我就不在这边啰嗦的,Google一下就有 ...
- ASP.NET MVC3开发-数据库篇之CodeFisrt开发(一)
本文讲述了在ASP.NET MVC3开发中M层使用Code Fisrt如何进行开发,由于作者对ASP.NET MVC3的学习不是很深,所以写的都是些基本的内容(写的如有不正确的地方请评论指正),适合初 ...
- 跟我一起玩转Sencha Touch 移动 WebApp 开发1
跟我一起玩转Sencha Touch 移动 WebApp 开发(一) 1.目录 移动框架简介,为什么选择Sencha Touch? 环境搭建 创建项目框架,框架文件简介 创建简单Tabpanel案例 ...
- 解决GOOGLE不能用的办法
解决GOOGLE不能用的办法 首先平时用用百度还是足够了,但是说实话,百度在进行一些尝试搜索时真的没GOOGLE好用,经常找到一大堆广告,却不是自己想要的,比如搜索里面的双引号.and.site.fi ...
- cubie两种固定MAC地址的方法
1.修改 /etc/init.d/networking 配置文件 在(a)代码的后面添加上(b)这段代码 (a)case "$1" in start) :5e #MAC地址可改 2 ...
- ASP.NET Web API的消息处理管道: HttpRoutingDispatcher
ASP.NET Web API的消息处理管道: HttpRoutingDispatcher 认情况下,作为消息处理管道“龙头”的HttpServer的Dispatcher属性返回一个HttpRouti ...
- VS简单注释插件——VS插件开发续
VS简单注释插件——VS插件开发续 前些时候,我写过一篇<VS版权信息插件——初试VS插件开发小记>分享过一个用于添加注释信息的插件,但那个插件有几个问题: 不能添加带块注释(/**/), ...