《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

【慧创近红外脑功能成像(fNIRS)】经皮耳迷走神经电刺激联用应用集锦

在这项双盲、随机、对照的试验中,将40例亚急性脑卒中患者随机分为两组:VNS组(VG)在TOT期间接受taVNS治疗,假手术组(SG)在TOT期间接受假taVNS治疗。此外,fNIRS显示,与SG相比,VG的对侧前额叶皮层和同侧感觉运动皮层的激活增加。然而,HRV组间无显著差异。结合taVNS技术,不仅能够探索taVNS对大脑功能产生的具体影响,还能通过精细调整刺激参数,进一步优化治疗效果,使之更加精准高效。这种治疗模式的创新,有望显著提升患者的治疗效果,改善其生活质量,为神经系统疾病的康复开辟新途径。

m0_75194604的博客 1139

手把手解决GD32H759I-EVAL以太网通信三大坑:IP冲突、端口绑定失败、LWIP内存泄漏

本文针对GD32H759I-EVAL开发板在以太网通信调试中常见的三大难题——IP地址冲突、端口绑定失败和LWIP内存泄漏,提供了详细的实战排障指南。文章深入分析了问题根源,并给出了具体的网络配置、端口管理策略和内存泄漏检测方法,帮助开发者快速定位并解决嵌入式网络通信中的棘手问题,确保系统稳定运行。

weixin_29196315的博客 139

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

【49】Camunda8-Self-Managed部署之Docker方式

围绕camunda8 self-managed,介绍了基于Docker部署相关服务的过程。

AlieNeny的博客 1682

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

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

DENGXI1997的博客 5313

银河麒麟鲲鹏aarch64架构安装docker和K8s

鲲鹏云服务器上安装docker-云社区-华为云 (huaweicloud.com) 这里我下载的版本是docker-18.09.3.tag docker 安装包地址:https://download.docker.com/linux/static/stable 配置system服务 在github对应分支的contrib/init/systemd/ 下面,提供了对应的docker.service以及docker.socket文件,可以直接拷贝到本地文件使用: 对应链接:https://github.c

qq_50007696的博客 9056

智能汽车域控制器FOTA升级方案探讨

上文提到的Entry属性,包括Active 属性, Bootable 属性, Successful 属性, Retrycnt 属性 ,Active 属性用于标志槽的优先级,bootloader优先选择Active 属性=1的槽启动,Bootable 属性标志槽可否可启动,Successful 属性标志槽是否成功启动过,Retrycnt 属性标志槽可尝试启动的次数。芯片启动后,首先进入Bootloader阶段,此阶段将读取存储系统的分区属性,根据属性值进行逻辑判断,并确定进入哪个分区,详见流程图。

huibian1234的博客 1570

C# 文件 文件夹 解除占用

C# 文件 文件夹 解除占用

9.歌工作室 1626

Rockchip RK3566 Buildroot SDK构建与内核编译实战指南

嵌入式Linux开发中,交叉编译环境是系统启动的基础支撑。Buildroot作为轻量级嵌入式构建框架,通过配置驱动、自动化下载和分层编译机制,显著降低定制化Linux发行版的集成门槛。其核心价值在于将内核、根文件系统与工具链统一管理,兼顾资源约束下的确定性构建与工程可复现性。典型应用场景涵盖ARM64平台(如RK3566)的固件开发、IoT设备量产镜像生成及硬件Bring-up阶段的快速验证。本文围绕Buildroot SDK全流程实践,深入解析环境搭建、Repo源码同步、离线DL库预置及内核编译等关键环节

weixin_36047538的博客 134

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

在 ABAP Cloud 中玩转 CL_ABAP_PARALLEL 并行处理:从原理到实战

ABAP并行处理框架CL_ABAP_PARALLEL解析 本文系统介绍了SAP ABAP环境中实现并行处理的CL_ABAP_PARALLEL框架。该框架通过封装异步RFC和对话进程,为开发者提供了面向对象的API,显著提升大批量数据处理的效率。 文章首先分析了ABAP环境需要并行处理的原因:传统的串行处理在面对百万级数据时效率低下。然后详细介绍了CL_ABAP_PARALLEL的设计思路,它是一个"小型线程池"式的同步并行框架,适用于批量计算场景。此外,文章重点讲解了控制并行任务的关键参

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 339

odom反算成经纬度

这个转换系统能够将局部坐标(相对于原点的X, Y, Z坐标)转换回全球坐标系统。将局部里程计数据反算成经纬度坐标的过程涉及几个关键步骤,主要是将相对于某个局部参考点的坐标(例如在机器人、无人车或无人机的导航系统中使用的坐标)转换回全球GPS坐标系统(WGS-84经纬度)。为了能够将局部里程计数据转换为经纬度,首先需要知道局部坐标系统的原点(即参考点)在全球坐标系统中的位置。对于从里程计获得的每个局部坐标点,使用步骤2中设置的坐标转换系统将其转换为经纬度。使用转换模型将局部坐标转换为全球坐标。

如果想成为中心,那么就到中心去吧。 650

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

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

尹自强.DoSomething() 534

精雕软件(JDpaint) 5.5 绿色版

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

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

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

weixin_30922589的博客 147

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

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

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

《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、付费专栏及课程。

余额充值