public string ToXML()  

        {  

            string strXml = string.Empty;  

            try  

            {  

                MemoryStream ms = new MemoryStream();  

                XmlSerializer xml = new XmlSerializer(this.GetType());  

                xml.Serialize(ms, this);  

                byte[] arr = ms.ToArray();  

                strXml = Encoding.UTF8.GetString(arr, , arr.Length);  

                return strXml;  

            }  

            catch  

            {  

                return "";  

            }  

        }  

象MemoryStream这类资源,应该用using包起来自动释放资源,否则会有内存泄漏问题。在using的使用上,我也同意应该使用using,但由于这类风格的代码在原项目中非常多(有一部分历史原因),如果一一修改,工作量太大,时间不允许。于是我就在内心评估:如果不改,现在这种代码的风险到底有多大?

我想很多人都知道using(Resource res = new Resrouce){},其实相当于

Resource res = new Resrouce

try{}

catch{}

finally{res.Dispose();}

对比与现有代码的区别,无非就是资源没有调用Dispose()释放,但是CLR有强大的GC(垃圾回收)机制,方法调用完成后,方法体中创建的托管资源如果不再被使用,也一并会被GC列为可回收对象,所以就算开发人员没有手动调用Dispose,其实CLR也会帮我们做这件事情,只是时机可能会晚一些而已。

于是有了下面的测试:

1.先创建一个示例用的Class

using System;  

using System.Collections.Generic;  

using System.Linq;  

using System.Text;  

using System.IO;  

using System.Xml.Serialization;  

namespace Model  

{  

    public class SampleClass  

    {  

        public string Name { set; get; }  

        public string ToXMLNoUsing()  

        {  

            string strXml = string.Empty;  

            try  

            {  

                MemoryStream ms = new MemoryStream();  

                XmlSerializer xml = new XmlSerializer(this.GetType());  

                xml.Serialize(ms, this);  

                byte[] arr = ms.ToArray();  

                strXml = Encoding.UTF8.GetString(arr, , arr.Length);  

                return strXml;  

            }  

            catch  

            {  

                return "";  

            }  

        }  

        public string ToXMLWithUsing()  

        {  

            string strXml = string.Empty;  

            try  

            {  

                using (MemoryStream ms = new MemoryStream())  

                {  

                    XmlSerializer xml = new XmlSerializer(this.GetType());  

                    xml.Serialize(ms, this);  

                    byte[] arr = ms.ToArray();  

                    strXml = Encoding.UTF8.GetString(arr, , arr.Length);  

                }  

                return strXml;  

            }  

            catch  

            {  

                return "";  

            }  

        }  

    }  

}   

这其中的ToXML为了测试方便,故意分成了二个版本(一个不用using,一个用using)

2.再创建一个Console程序(命名为WithUsing),写一段测试代码:

using System;  

using System.Diagnostics;  

using Model;  

namespace WithUsing  

{  

    class Program  

    {  

        static void Main(string[] args)  

        {  

            Console.WriteLine("开始折腾-WithUsing...");  

            Stopwatch watch = new Stopwatch();  

            int max = ;  

            watch.Reset();  

            watch.Start();  

            for (int i = ; i < max; i++)  

            {  

                SampleClass c = new SampleClass() { Name = i.ToString().PadLeft(, '') };  

                c.ToXMLWithUsing();  

            }  

            watch.Stop();  

            Console.WriteLine("完成,{0}次操作共耗时:{1}毫秒,平均{2}毫秒/次!", max, watch.ElapsedMilliseconds, watch.ElapsedMilliseconds /(decimal)max);  

            Console.ReadKey();  

        }  

    }  

}  

3.再创建一个Console程序(命名为NoUsing),写一段测试代码:

using System;  

using System.Diagnostics;  

using Model;  

namespace NoUsing  

{  

    class Program  

    {  

        static void Main(string[] args)  

        {  

            Console.WriteLine("开始折腾-NoUsing...");  

            Stopwatch watch = new Stopwatch();  

            int max = ;  

            watch.Reset();  

            watch.Start();  

            for (int i = ; i < max; i++)  

            {  

                SampleClass c = new SampleClass() { Name = i.ToString().PadLeft(, '') };  

                c.ToXMLNoUsing();  

            }  

            watch.Stop();  

            Console.WriteLine("完成,{0}次操作共耗时:{1}毫秒,平均{2}毫秒/次!", max, watch.ElapsedMilliseconds, watch.ElapsedMilliseconds / (decimal)max);  

            Console.ReadKey();  

        }  

    }  

}  

编译后,同时运行这二个程序,同时利用任务管理器观察内存使用情况:

反复多次运行比较,发现其实二者占用的内存几乎完全相同,这说明GC还是很给力的!

而且从执行时间上看,不用Using,反而更快,这也容易理解:用Using相当于每次都要调用Dispose()方法,这会带来一些系统开销;而不用Using,GC会在适当的时机批量回收资源,性能反而更好。(当然:这个结论不是要误导大家不用using,对于using还是推荐使用的!我的用意在于大家对于一些具体问题要具体分析,不可纯教条主义,一味迷信某些主流的观点)

作者:菩提树下的杨过
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
 
 

c#:使用using关键字自动释放资源未必一定就会有明显好处的更多相关文章

  1. Notepad++ JSON关键字自动提示

    Notepad++关键字自动提示 2017-08-31 目录 1 插件安装2 往JSON中加关键字3 智能提示 最近接口测试自动化框架的的case是json格式,用例的json的格式是固定的,定义专门 ...

  2. 帝国cms内容关键字自动加链接且设置内容关键字只替换一次

    网站上线前先设置一些内部链接对后期的优化排名很有帮助,帝国cms也可以设置文章中的关键字自动加链接,但是要注意一下关键词替换次数,最好是1次. 怎么操作呢?分两步完成 1.帝国cms文章关键字自动加链 ...

  3. java7(3)——增强的catch之自动释放资源

    跟mutilcatch一样,java7提供了自动释放资源的方法,但还是很少看到人使用,估计是麻烦去重写close方法.不过jdk内部一些类已经改成使用增强的catch来释放资源的写法,所以我们有必要了 ...

  4. using 自动释放资源示例

    我们在使用SqlConnection的时候可以加入using,那么在using语句结束后就会自动关闭连接.那么这种情况是怎么是实现的呢?我们能够自己写一个类似于SqlConnection的类来让usi ...

  5. 搜索关键字自动更正 - Oracle Endeca Server

    做了几个Oracle Endeca 电商项目.每个项目都会有搜过关键字拼写错误更正(Spelling Correction)的需求.淘宝也有类似功能. Oracle Endeca Sever提供了关键 ...

  6. XML文件中关键字自动提示和不全配置

    一.获得mybatis-3-config.dtd.mybatis-3-mapper.dtd 这两个文件. 建立一个Maven的项目 在Pom.xml文件中的Mybatis jar包的下载设置(也可以从 ...

  7. try(){}自动释放资源,AutoCloseable

    我们在使用资源的时候,必须关闭资源,比如使用jdbc连接或者inputStream的时候,必须在finally中将资源关闭.然而有的时候我们会忘记关闭资源.那么有没有更好的方法呢? SqlSessio ...

  8. Eclipse 实现关键字自动补全功能

    一般默认情况下,Eclipse ,MyEclipse 的代码提示功能是比Microsoft Visual Studio的差很多的,主要是Eclipse ,MyEclipse本身有很多选项是默认关闭的, ...

  9. Eclipse 实现关键字自动补全功能 (转)

    一般默认情况下,Eclipse ,MyEclipse 的代码提示功能是比Microsoft Visual Studio的差很多的,主要是Eclipse ,MyEclipse本身有很多选项是默认关闭的, ...

随机推荐

  1. scipy稀疏矩阵

    那些零元素数目远远多于非零元素数目,并且非零元素的分布没有规律的矩阵称为稀疏矩阵(sparse matrix). 不同类型的矩阵有不同的压缩方式,比如对角矩阵只存储对角元素即可.要想充分压缩,就要找到 ...

  2. Java反编译工具:Java Decompiler

    Java Decompiler项目旨在开发一套工具集,这套工具集可以反编译并分析Java5之后的Java字节码. 它主要包括四个部分. JD-Core:Java Decompiler的核心库,它能够根 ...

  3. IT公司管理发展经验

        2012-11-14 内容存档在evernote,笔记名"IT公司管理发展经验"

  4. k8s实战之Service

    一.概述 为了适应快速的业务需求,微服务架构已经逐渐成为主流,微服务架构的应用需要有非常好的服务编排支持,k8s中的核心要素Service便提供了一套简化的服务代理和发现机制,天然适应微服务架构,任何 ...

  5. Pusher 消息推送测试工具

    1.Pusher 简介 Pusher 是一款为 iOS.Mac App 提供推送测试的小工具. 其它下载地址 Pusher v0.7.3 for Mac,密码:p19i. 2.使用方法 使用方法简介 ...

  6. 技术的正宗与野路子 c#, AOP动态代理实现动态权限控制(一) 探索基于.NET下实现一句话木马之asmx篇 asp.net core 系列 9 环境(Development、Staging 、Production)

    黄衫女子的武功似乎与周芷若乃是一路,飘忽灵动,变幻无方,但举手抬足之间却是正而不邪,如说周芷若形似鬼魅,那黄衫女子便是态拟神仙. 这段描写出自<倚天屠龙记>第三十八回. “九阴神抓”本是& ...

  7. c#之hello world

    前言:公司开始转型java,作为javaer,负责其他同事转型,期间以为工作需要,需要简单学习c#语法,顾有此文,及其后续的一系列文章(c#里头的一些优点,可以为提升java的思想带来帮助) 1. 安 ...

  8. html5 ajax 文件上传

    http://html5demos.com/dnd-upload 看这个例子看了一会儿...这个是支持拖拽的上传. 下面代码是一个简单的ajax的文件上传: function match(url,rs ...

  9. CentOS安装OpenResty(Nginx+Lua)开发环境

    一.简介 OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库.第三方模块以及大多数的依赖项.用于方便地搭建能够处理超高并发.扩展性极高 ...

  10. Linux 密码过期(WARNING:Your password has expired )

    最近遇到两次这个问题,我们公司用的是开源的堡垒机Jumpserver但是最近有两个同学遇到了 WARNING:Your password has expired 第一次遇到这个问题也没有往深了去查,当 ...