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: ...
随机推荐
- CSS盒模型和定位的类型
此文根据Steven Bradley的<How Well Do You Understand CSS Positioning?>所译,整个译文带有我自己的理解与思想,如果译得不好或不对之处 ...
- namespace 的作用
在写CPP的时候,常常要写using namespace std;这么一句话,到底有什么用呢? #include <iostream> namespace first { ; } name ...
- 讲讲Linq to SQL映射(基础篇)
讲讲Linq to SQL映射(基础篇) 这篇主要讲Linq to SQL基于属性的映射.即映射数据库,映射表,映射列,映射关系,映射存储过程, 映射函数.然而创建这种映射有三种方法,他们分别是OR ...
- js正则验证邮箱格式
首先总结一下邮箱的格式,邮箱由@分隔,左侧为用户名,右侧为邮箱域名,用户名可以由字母.数字._.-以及.组成,但是必须是以字母或数字开头,邮箱的域名是由字母.数字.-和.组成的,但是必须以.加上字母的 ...
- Ajax实现天气预报功能
实现天气预报功能 闲来无聊,写下此文 经常看见很多网站上有那种天气预报功能,自己之前也写过一个,不过属于那种涉及WCF服务引用那种,今天发现一个更为简单的方式来实现,使用Javascript和Ajax ...
- 分享Mvc3+NInject+EF+LigerUI权限系统Demo
前段时间时不时看到有园友的分享权限系统,于是本人突发奇想,也想写一个玩玩,就利用晚上时间,陆陆续续花了一周多样子,写了如今这个权限系统,这个权限系统具有 组织结构.用户.角色.菜单,组织结构下挂用户, ...
- linux学习之linux的hostname修改详解《转》
linux的hostname是一个kernel变量,可以通过hostname命令来查看本机的hostname.也可以直接cat /proc/sys/kernel/hostname查看. #hostna ...
- DNS:域名系统
DNS:域名系统 1.DNS DNS 是计算机域名系统(Domain Name System 或Domain Name Service) 的缩写,它是由解析器以及域名服务器组成的.域名服务器 ...
- 在C#中模拟Javascript的setTimeout方法
在C#中模拟Javascript的setTimeout方法 背景 每种语言都有自己的定时器(Timer),很多人熟悉Javascript中的setInterval和setTimeout,在Javasc ...
- memcached 命令操作详解
memcached 命令操作详解 一.存储命令 存储命令的格式: <command name> <key> <flags> <exptime> < ...