利用using和try/finally语句来清理资源
使用非托管资源的类型必须实现IDisposable接口的Dispose()方法来精确的释放系统资源。.Net环境的这一规则使得释放资源代码的职责 是类型的使用者,而不是类型或系统。因此,任何时候你在使用一个有Dispose()方法的类型时,你就有责任来调用Dispose()方法来释放资源。 最好的方法来保证Dispose()被调用的结构是使用using语句或者try/finally块。
所有包含非托管资源的类型应该实现IDisposable接口,另外,当你忘记恰当的处理这些类型时,它们会被动的创建析构函数。如果你忘记处理这些对 象,那些非内存资源会在晚些时候,析构函数被确切调用时得到释放。这就使得这些对象在内存时待的时间更长,从而会使你的应用程序会因系统资源占用太多而速 度下降。
幸运的是,C#语言的设计者精确的释放资源是一个常见的任务。他们添加了一个关键字来使这变得简单了。假设你写了下面的代码:public void ExecuteCommand( string connString, string commandString )
{
SqlConnection myConnection = new SqlConnection( connString );
SqlCommand mySqlCommand = new SqlCommand( commandString, myConnection );
myConnection.Open();
mySqlCommand.ExecuteNonQuery();
}
这个例子中的两个可处理对象没有被恰当的释放:SqlConnection和SqlCommand。两个对象同时保存在内存里直到析构函数被调用。(这两 个类都是从System.ComponentModel.Component继承来的。)
解决这个问题的方法就是在使用完命令和链接后就调用它们的Dispose:
- public void ExecuteCommand( string connString, string commandString )
- {
- SqlConnection myConnection = new SqlConnection( connString );
- SqlCommand mySqlCommand = new SqlCommand( commandString,
- myConnection );
- myConnection.Open();
- mySqlCommand.ExecuteNonQuery();
- mySqlCommand.Dispose( );
- myConnection.Dispose( );
- }
这很好,除非SQL命令在执行时抛出异常,这时你的Dispose()调用就永远不会成功。using语句可以确保Dispose()方法被调用。当你把 对象分配到using语句内时,C#的编译器就把这些对象放到一个try/finally块内:
- public void ExecuteCommand( string connString,
- string commandString )
- {
- using ( SqlConnection myConnection = new
- SqlConnection( connString ))
- {
- using ( SqlCommand mySqlCommand = new
- SqlCommand( commandString,
- myConnection ))
- {
- myConnection.Open();
- mySqlCommand.ExecuteNonQuery();
- }
- }
- }
当你在一个函数内使用一个可处理对象时,using语句是最简单的方法来保证这个对象被恰当的处理掉。当这些对象被分配时,会被编译器放到一个 try/finally块中。下面的两段代码编译成的IL是一样的:
- SqlConnection myConnection = null;
- // Example Using clause:
- using ( myConnection = new SqlConnection( connString ))
- {
- myConnection.Open();
- }
- // example Try / Catch block:
- try {
- myConnection = new SqlConnection( connString );
- myConnection.Open();
- }
- finally {
- myConnection.Dispose( );
- }
如果你把一个不能处理类型的变量放置在using语句内,C#编译器给出一个错误,例如:
- // Does not compile:
- // String is sealed, and does not support IDisposable.
- using( string msg = "This is a message" )
- Console.WriteLine( msg );
using只能在编译时,那些支持IDispose接口的类型可以使用,并不是任意的对象:
- // Does not compile.
- // Object does not support IDisposable.
- using ( object obj = Factory.CreateResource( ))
- Console.WriteLine( obj.ToString( ));
如果obj实现了IDispose接口,那么using语句就会生成资源清理代码,如果不是,using就退化成使用using(null),这是安全 的,但没有任何作用。如果你对一个对象是否应该放在using语句中不是很确定,宁可为了更安全:假设要这样做,而且按前面的方法把它放到using语句 中。
这里讲了一个简单的情况:无论何时,当你在某个方法内使用一个可处理对象时,把这个对象放在using语句内。现在你学习一些更复杂的应用。还是前面那个 例子里须要释放的两个对象:链接和命令。前面的例子告诉你创建了两个不同的using语句,一个包含一个可处理对象。每个using语句就生成了一个不同 的try/finally块。等效于你写了这样的代码:
- public void ExecuteCommand( string connString,
- string commandString )
- {
- SqlConnection myConnection = null;
- SqlCommand mySqlCommand = null;
- try
- {
- myConnection = new SqlConnection( connString );
- try
- {
- mySqlCommand = new SqlCommand( commandString,
- &nbs
利用using和try/finally语句来清理资源的更多相关文章
- Azure Terraform(十)利用 Azure DevOps 的条件语句选择发布环境
一,引言 之前我讲过的所有的案例中,都是将整个Azure Resource 部署到同一个订阅下,没有做到灵活的在 Azure Pipeline 在运行前选择需要部署的环境.在实际的项目开发中,我们也会 ...
- using强制对象清理资源 【转】
转 http://www.cnblogs.com/Legolas/p/detail-of-using.html using肯定所有人都用过,最简单的就是使用using引入命名空间,然后就是引入别名,简 ...
- 利用dbms_metadata.get_ddl查看DDL语句
http://www.cnblogs.com/aocle/archive/2011/10/13/2209790.html 当我们想要查看某个表或者是表空间的DDL的时候,可以利用dbms_metada ...
- Oracle利用dbms_metadata.get_ddl查看DDL语句
当我们想要查看某个表或者是表空间的DDL的时候,可以利用dbms_metadata.get_ddl这个包来查看. dbms_metadata包中的get_ddl函数详细参数 GET_DDL函数返回创建 ...
- iOS利用SDWebImage实现缓存的计算与清理
概述 可以仅仅清理图片缓存, 也可以清理所有的缓存文件(包括图片.视频.音频等). 详细 代码下载:http://www.demodashi.com/demo/10717.html 一般我们项目中的缓 ...
- 利用正则表达式类解析SQL语句,达到Worklist兼容各个RIS数据库的目的
在做RIS的项目中遇到一个问题, 因为Worklist要兼容各个RIS数据库, 因此设计了目前这个架构. 1.xml文件来配置RIS数据库的数据源, 2.xml文件来存储关于查询/更新数据库的SQL语 ...
- 利用反射自动生成SQL语句(仿Linq)
转:http://www.cnblogs.com/the7stroke/archive/2012/04/22/2465597.html using System; using System.Colle ...
- powershell利用winform批量执行tsql语句
#加载.net的winform模块 [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") $app= ...
- JS利用短路原理简写if语句
看GoogleDoodle-Dance的源代码,学习到一个小知识——简写if语句. 几乎所有语言中||和&&都遵循“短路”原理,如&&中第一个表达式为假就不会去处理第二 ...
随机推荐
- ACM学习历程—HDU5666 Segment(数论)
http://acm.hdu.edu.cn/showproblem.php?pid=5666 这题的关键是q为质数,不妨设线段上点(x0, y0),则x0+y0=q. 那么直线方程则为y = y0/x ...
- Yii 常用命令
一.Yii的Active Recorder包装了很多. 特别是把SQL中 把where,order,limit,IN/not IN,like等常用短句都包含进CDbCriteria这个类中去,这样整个 ...
- My97DatePicker 和转换 数据库中日期(/Date(1351699200000)/) 的格式
一 转换 数据库中日期(/Date(1351699200000)/) 的格式: C#中转换日期格式 var date=com.CREATEDATETIME.ToString(); JavaScrip ...
- 蓝桥杯 算法训练 ALGO-146 4-2找公倍数
算法训练 4-2找公倍数 时间限制:1.0s 内存限制:256.0MB 查看参考代码 问题描述 这里写问题描述. 打印出1-1000所有11和17的公倍数. 样例输入 一个满足题 ...
- 【转】LTE-NAS过程学习总结
为了从网络得到非接入层服务,网络中非接入层节点必须知道有关UE的信息.为了这个目的,UE不得不发起附属过程,该过程是在UE开机和初始接入网络时必须被执行的. 一旦该过程成功,MME上就会建立好一个该U ...
- SpringBoot自动化配置之四:SpringBoot 之Starter(自动配置)、Command-line runners
Spring Boot Starter是在SpringBoot组件中被提出来的一种概念,stackoverflow上面已经有人概括了这个starter是什么东西,想看完整的回答戳这里 Starter ...
- [cinder] volume type 使用简记
cinder type-create sharecinder type-key share set volume_backend_name=GLUSTERFScinder type-create lo ...
- socket关闭
首先应该了解win32 api closesocket,这里只说msdn文档中叙述不够清晰的地方. 首先说缺省情况:l_onoff为0,closesocket立刻返回,但底层依然在持续发包,并且试图优 ...
- C# Dynamic通用反序列化Json类型并遍历属性比较
背景 : 最近在做JAVA 3D API重写,重写的结果需要与原有的API结果进行比较,只有结果一致时才能说明接口是等价重写的,为此需要做一个API结果比较的工具,比较的内容就是Json内容,但是为了 ...
- python IOError: windows directory not found at xxxxx win32
您需要修改 PATH 环境变量,将Python的可执行程序及额外的脚本添加到系统路径中.将以下路径添加到 PATH 中: C:\Python2.7\;C:\Python2.7\Scripts\;请打开 ...