《Effective C#》Item 15:利用using和try-finally来释放资源

C#核心特性与开发实践全解析 面向对象编程是现代软件开发的基础范式,C#作为.NET平台的主力语言,通过统一的类型系统和自动内存管理机制实现了高效开发。其核心特性包括泛型编程确保类型安全、LINQ实现声明式数据操作、async/await简化异步编程,这些技术显著提升了工程实践中的开发效率和代码质量。特别是在企业级应用开发中,C#的反射机制和特性系统为元编程提供了强大支持,而委托与事件模型则完善了观察者模式的实现。随着.NET生态的跨平台发展,C#结合Visual Studio等工具链,已成为Web服务、桌面应用和游戏开发等场景的热门选 阅读详情

我以前写过一篇文章,关于.Net资源释放问题,也就是对于非内存的资源,最好使用IDisposable接口提供的Dispose来释放,详情参看这篇文章。

http://blog.youkuaiyun.com/knight94/archive/2006/08/05/1023352.aspx

 

很明显,Dispose方法是一个外部方法,系统并不会帮你调用。为了尽早释放对象所占用的资源,所以需要保证Dispose方法能尽早被执行。那么在.Net中提供了一个比较简便的方法,就是对于实现了IDisposable接口的类型对象提供了using语句。

 

就操作一个数据库这个例子来说,使用using语句可以如下:

    using( SqlConnection sqlConn = new SqlConnection( yourConnectionString ) )

    {

        sqlConn.Open();//Open connection

   

        //Operate DB here using "sqlConn"  

 

        sqlConn.Close();//Close connection

    }

 

但是有时候当多个对象需要释放的候,例如:

    SqlConnection sqlConn = new SqlConnection( yourConnectionString );

    SqlCommand sqlComm = new SqlCommand( yourQueryString, sqlConn );

    using(sqlConn as IDisposable)

    using(sqlComm as IDisposable)

    {

        sqlConn.Open();//Open connection

   

        sqlComm.ExecuteNonQuery();//Operate DB here

    }

 

这时候要特别注意,需要确保在发生异常的情况下,所有对象都能正常释放。显然,这段程序块,当构造“sqlComm”对象发生异常,会造成“sqlConn”对象无法及时被释放。虽说构造函数内部很少发生异常,或者说编写程序的时候要尽量避免从构造函数内向外散发异常。不过这里所说的意思是,要尽量把需要释放的对象放到using或者try-catch程序块,并作局部的异常处理,避免异常造成有些对象没有被释放。那么改进的方法,例如可以如下。

    using( SqlConnection sqlConn = new SqlConnection( yourConnectionString ) )

    using( SqlCommand sqlComm = new SqlCommand( yourQueryString, sqlConn ) )

    {

        try

        {

            sqlConn.Open();//Open connection

            sqlComm.ExecuteNonQuery();//Operate DB here

        }

        catch( SqlException err )

        {

            MessageBox.Show( err.Message );

        }

        catch( Exception err )

        {

            MessageBox.Show( err.Message );

        }

    }

 

(如上,即使在构造“sqlComm”出现异常,也会释放“sqlConn”对象。同时在这里多谢 lmtz 网友对文章提出的异议,从而使我重新审查此文,并进行修正。)

 

但是对于using程序块来说,它有两个限制。

第一个就是using所对应的对象必须继承IDisposable,如果此对象没有继承IDisposable接口的话,系统会提示编译错误。

例如:

    using( string strMsg = "My Test" )

        Debug.WriteLine( strMsg );//Can't be compiled

 

第二个using对象检查是静态类型检查,并不支持运行时类型检查,因此如下形式也会出现编译错误。

    SqlConnection sqlConn = new SqlConnection( yourConnectionString );

    object objConn = sqlConn;

    using ( objConn )

    {

        Debug.WriteLine( objConn.ToString() );//Can't be compiled

    }

 

不过对于后者,可以通过“as”来进行类型转换方式来改进。

    SqlConnection sqlConn = new SqlConnection( yourConnectionString );

    object objConn = sqlConn;

    using ( objConn as IDisposable )

    {

        Debug.WriteLine( objConn.ToString() );

    }

 

对于Dispose函数的调用来说,使用using程序块来完成只是最常用的方法,除此外,还可以用try-finally来完成,例如:

    SqlConnection sqlConn = new SqlConnection( yourConnectionString );

    try

    {

        sqlConn.Open();

       

        //Operate DB here using "sqlConn"

    }

    finally

    {

        if( sqlConn != null )

            sqlConn.Dispose();

    }

 

为了及早释放对象所占用的非托管资源,因此要保证Dispose方法能在使用完对象后被调用,.Net提供了using程序块和try-finally程序块两个方法,两者并没有太大的区别,可能使用using能使程序看得比较简明,但是为了防止异常,需要在using中加入try-catch,这样反而不如try-finally看得舒服,不过这也只是我个人的看法。总的来说,只要把方法合理整合到应用程序当中才是最重要的。

C# 清理垃圾文件(最新) @echo off echo C:\WINDOWS\Temp del /f /s /q "%windir%\Temp\*.*" echo C:\Documents and Settings\UserName\Local Settings\Temp del /f /s /q "%userprofile%\Local Settings\Temp\*.*" echo C:\Documents and Settings\UserName\Local Settings\Temporary Internet Files del /f /s /q "%userprofile%\Local Settings\Temporary Internet Files\*.*" echo C:\Documents and Settings\UserName\Cookies del /f /s /q "%userprofile%\Cookies\*.*" echo C:\Documents and Settings\UserName\Recent del /f /s /q "%userprofile%\Recent\*.*" 我的博客:http://hi.baidu.com/kingzhexian/blog 立即下载

相关推荐

.NET清除工具 2.0-4.5.2

* .NET Framework - All Versions * .NET Framework - All Versions (Tablet PC and Media Center) * .NET Framework - All Versions (Windows Server 2003) * .NET Framework - All Versions (Windows Vista and Windows Server 2008) * .NET Framework 1.0 * .NET Framework 1.1 * .NET Framework 2.0 * .NET Framework 3.0 * .NET Framework 3.5 * .NET Framework 4 * .NET Framework 4.5 * .NET Framework 4.5.1 * .NET Framework 4.5.2

【语言-c#】文件被占用如何解除

1、加载文件后,删除文件时提示如下 文件“..jpg”正由另一进程使用,因此该进程无法访问此文件。 背景 C# 中使用Image.FromFile(string path)并使用System.IO.File.Delete(string path)后提示该文件正在被另一进程使用XXX的问题,是因为对应的文件在一直使用中 ,其生成的 Image 对象被 Disponse() 前都不会被解...

少莫千华 1万+

.net全系列清理工具

.NET Framework 1.0 .NET Framework 1.1 .NET Framework 2.0 .NET Framework 3.0 .NET Framework 3.5 .NET Framework 4 .NET Framework 4.5 .NET Framework 4.5.1 .NET Framework 4.5.2 .NET Framework 4.6 .NET Framework 4.6.1 .NET Framework 4.6.2 .NET Framework 4.7 .NET Framework 4.7.1 .NET Framework 4.7.2

c#、.net 清理电脑内存 非常暴力

【代码】c#、.net 清理电脑内存 非常暴力。

qq_40934195的博客 748

十一、学生信息管理系统(PyQt5+MySQL+PyMySQL模块实现)

学生信息管理系统(PyQt5+MySQL+PyMySQL模块实现)

ungoing的博客 8991

Windows下快速搭建Kettle开发环境:基于9.4.0.0版本的保姆级教程

本文提供Windows系统下Kettle 9.4.0.0开发环境的详细搭建指南,涵盖源码获取、Maven配置优化、高效编译及部署运行全流程。通过实战验证的步骤和常见问题解决方案,帮助数据工程师快速完成环境配置,提升ETL开发效率。

weixin_28829479的博客 330

c#删除文件被占用无法删除的解决方案

FileStream fileStream = new FileStream(filePath, FileMode.Open,FileAccess.Read); int byteLength = (int)fileStream.Length; byte[] fileBytes = new byte[byteLength]; fileStream.Read(fileBytes, 0, byt...

HKP1992的博客 5025

电源完整性必看!用SIwave提取PDN阻抗曲线的3个关键设置与常见报错解决

本文深入探讨了在SIwave中进行电源完整性(PI)仿真时,提取PDN阻抗曲线的三个核心设置要点。重点解析了端口阻抗设为0.1欧姆的物理意义与SYZ参数仿真中的阻抗匹配原则,并提供了针对常见收敛性问题和模型误差的实战排查思路,旨在帮助工程师获得更精确可靠的仿真结果,为去耦电容优化提供依据。

b9c0d的博客 351

C# 删除或修改文件时提示文件被占用

C# 中使用Image.FromFile(string path)后,提示该文件正在被另一进程使用XXX的问题,是因为对应的文件在一直调用 ,其生成的Image对象被Disponse()前都不会被解除锁定,这就造成了此问题,就是在这个图形被解锁前无法对图像进行操作(比如删除,修改等操作)。 解决方案:此问题可以使用下面三个方法解决问题. 方法1:在要进行文件操作前将Image对象销毁. Syste...

DENGXI1997的博客 5313

【车载开发系列】ParaSoft单元测试环境配置(一)

bdf是数据文件的一种类型,表示一种数据库文件。在ParaSoft当中,可以使用bdf文件来快速创建一个测试项目。

千月星跡 2147

【AI实战】用Coze工作流打造抖音视频文案提取神器——从单链接到批量处理的进阶指南

本文详细介绍了如何利用Coze工作流打造抖音视频文案提取工具,从单链接处理到批量提取的进阶指南。通过AI技术和工作流的结合,用户可以高效提取抖音视频的ASR和OCR文本,大幅提升内容创作效率。文章还涵盖了性能优化、异常处理及实际应用场景扩展,助力开发者快速实现抖音文案自动化提取。

weixin_29210759的博客 278

C# 文件 文件夹 解除占用

C# 文件 文件夹 解除占用

9.歌工作室 1626

图神经网络学习笔记-点云数据处理(专题七)

本教程解释了如何利用图神经网络(Graph Neural Networks,GNNs)来处理和训练点云数据。尽管点云默认情况下不具有图结构,但我们可以利用 PyG 的转换工具,将其转化为适合 PyG 所提供的全套 GNN 模型的形式。关键思想是从点云数据中创建一个,通过 GNN 的消息传递机制,从中学习有意义的局部几何结构。这些点的表示可以被用于例如点云分类或分割等任务。

351

Effective C# Item 15: Utilize using and try/finally for Resource Cleanup

Effective C# Item 15: Utilize using and try/finally for Resource Cleanup 当我们使用非托管资源(unmanaged resources)类型时,应当使用IDisposable接口的Dispose()方法来释放资源。在.Net环境中,对非托管资源的回收不是系统的责任,我们必须自己调用Dispose()方法...

aijinyao5713的博客 289

Google Earth Engine(GEE)——全球影像数据正确下载方式和注意事项

今天看到有人担心全球影像能不能下载的问题? 有时候我们会用到全球的数据,但是如何下载全球的数据呢? 首先如果没有全球的矢量边界我们会不会无法下载全球的数据,答案当然是可以的,因为我们在边界筛选的过程中filterBounds(),就是为了筛选边界,当我们不进行边界筛选的时候,自然而然默认的边界范围就是全球的,但是紧接着会面临其他两个问题:1如何下载?2如何在不缩小分辨率的情况下下载成功? 对于第一个问题我们如何下载?还是按照正常的逻辑利用export直接倒出到Google硬盘当中, 代码:

此星光明博客 3770

如何让 Mac mini 24小时不休眠运行 OpenClaw

如果 OpenClaw 每 5-10 分钟自动退出,launchd 连续 4 次快速重启后会判定为崩溃循环并卸载服务。:方案一(pmset)+ 方案三(launchd)组合使用,既防止系统休眠,又保证 OpenClaw 开机自启和崩溃自动恢复。:caffeinate 只在进程运行期间有效,终端关闭或进程结束后系统恢复正常睡眠策略。这条命令会自动创建 launchd plist 并启用服务,是最推荐的方式。替换为你的实际用户名路径,Node.js 路径也要改成你自己的。确保 plist 中有。

Maynor的博客 2199

Effective C# Item15:利用using和try/finally语句来清理资源

在内存资源分配方面,.NET可以分为托管资源和非托管资源两部分。对于托管资源,.NET框架会负责进行垃圾回收的工作;对于非托管的资源,我们需要手动去释放资源。通常情况下,我们使用IDisposable接口中的Dispose()方法释放资源,而调用Dispose()方法的责任,由资源的拥有者或者对象的拥有者执行,即我们这些程序员,确保调用Dispose()方法的最佳方式就是使用using或者try/

尹自强.DoSomething() 534

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【转】Effective C# Item 15: Utilize using and try-finally

本文转自: 当我们使用非托管资源(unmanagedresources)类型时,应当使用IDisposable接口的Dispose()方法来释放资源。在.Net环境中,对非托管资源的回收不是系统的责任,我们必须自己调用Dispose()方法来释放资源。确保非托管资源会释放的最好方法是使用using或者try/finally。 所有的非托管资源类型都实现了IDisposabl...

weixin_30922589的博客 147

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Item 15: Utilize using and try/finally for Resource Cleanup(Effective C#)

  In some ways, resource management can be more difficult in C# than itwas in C++. You can’t rely on deterministic finalization to clean up everyresource you use. But a garbage-collected environment...

weixin_30915275的博客 153

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

《Effective C#》Item 16:尽量减少垃圾产生的数量

我以前写过一篇文章,关于.Net资源释放问题,也就是对于非内存的资源,最好使用IDisposable接口提供的Dispose来释放,详情参看这篇文章。http://blog.csdn.net/knight94/archive/2006/08/05/1023352.aspx 很明显,Dispose方法是一个外部方法,系统并不会帮你调用。为了尽早释放对象所占用的资源,所以需要保证Dispo

yangyangcong的专栏 311

C# 自动内存管理

一、垃圾回收 VES内置了垃圾回收支持,垃圾回收器只负责内存管理,它没有提供一个自动的系统来管理与内存无关的资源。 .NET的垃圾回收 多数CLI实现使用一个分代的(generational)、支持压缩的(compacting)、以及基于mark-and-sweep(标记并清除)的算法回收内存。 分代的:是因为只存活过短暂时间的对象与已经在垃圾回收时活下来的对象(原因是对象仍在使用)相比,前者会...

mozhi 805
上一篇: 《Effective C#》Item 14:使用构造函数初始化语句
下一篇: 《Effective C#》Item 16:尽量减少垃圾产生的数量
Knight94
博客等级 码龄25年 1013粉丝 87原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值