【转】.Net高级技术——IDisposable

IDisposable概述

  GC(垃圾收集器)只能回收托管(Managed内存资源,对于数据库连接、文件句柄、Socket连接等这些资源(非托管资源,UnManaged)就无能为例,必须程序员自己控制资源的回收。非托管资源:SqlConnection、FileStream等。

  对于使用非内存资源的类,完全可以自己定义一个销毁资源的方法来供程序员回收,.net推荐实现IDisposable接口(为了规范非托管资源的回收),在Dispose方法中进行回收。

  实现了IDisposable接口的对象都可以使用using进行资源管理。using就是帮我们做了:

1 FileStream fs = new F.....
2 try {
3 fs.read()....
4 }
5 finally {
6 fs.Dispose();
7 }

  实现了IDisposable接口的对象都要进行回收,否则很可能有内存泄露。

  非托管内存资源才需要实现IDisposable

IDisposable例子

 1 namespace 资源回收
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             //使用using对实现IDisposable的类了进行资源管理
 8 /*拿到一个对象的时候,首先判断这个对象是否实现了IDisposable接口,如果实现了,最好就用using包裹住这个对象,保证这个对象用完之后被释放掉,否则很可能出现资源泄露的问题
 9 */
10             using (Telphone t1 = new Telphone())
11             {
12                 t1.Open();
13                 t1.Speak("hello");
14                 t1.Bomb();
15                 //t1.Dispose();//如果在这里调用了Dispose()方法释放资源,那么在执行t1.Open()方法就出错,电话线已经被剪断了,无法再打电话了
16                 t1.Open();
17                 t1.Speak("I am back!");
18             }//代码执行到这里后,就会调用Dispose方法来进行资源回收
19             Console.ReadKey();
20         }
21     }
22     /// <summary>
23     /// Telphone类实现了IDisposable接口
24     /// </summary>
25     class Telphone : IDisposable
26     {
27         /// <summary>
28         /// 电话状态
29         /// </summary>
30         private TelphoneState state;
31         /// <summary>
32         /// 打电话
33         /// </summary>
34         public void Open()
35         {
36             if (state == TelphoneState.Disposed)
37             {
38                 throw new Exception("电话线已经被剪断,无法打开!");
39             }
40             state = TelphoneState.Open;
41             Console.WriteLine("拿起电话");
42         }
43         /// <summary>
44         /// 说话
45         /// </summary>
46         /// <param name="s">说话内容</param>
47         public void Speak(string s)
48         {
49             if (state != TelphoneState.Open)
50             {
51                 throw new Exception("没有连接");
52             }
53             Console.WriteLine(s);
54         }
55         /// <summary>
56         /// 挂掉电话
57         /// </summary>
58         public void Bomb()
59         {
60             state = TelphoneState.Close;
61             Console.WriteLine("挂掉电话");
62         }
63         #region IDisposable 成员
64         /// <summary>
65         /// 实现IDisposable接口中的Dispose()方法来释放非托管资源
66         /// 如何释放非托管资源由程序自己定
67         /// </summary>
68         public void Dispose()
69         {
70             if (state == TelphoneState.Open)
71             {
72                 Bomb();//挂掉电话
73             }
74             state = TelphoneState.Disposed;
75             Console.WriteLine("剪断电话线");
76         }
77         #endregion
78     }
79     /// <summary>
80     /// 电话状态枚举
81     /// </summary>
82     enum TelphoneState
83     {
84         Open, Close, Disposed
85     }
86 }

程序运行结果:

  Dispose中通常会顺便调用Close,这只是实现类自己的行为,没人强求, IDisposable中的 Dispose方法根本不知道Close方法的存在,甚至可以没有close方法。(Close与Dispose关系 常考)。没有规定Dispose一定会调用Close方法,但是很多的实现了IDisposable接口的方法中,通常都是代为调用Close之类的方法。一般的close只是关闭,也许关闭后还能打开,但是Dispose一般就表示资源被回收了,再也没法用了。有的类可能没有close方法。

Close和Dispose的区别:

1、一个类如果实现IDisposable接口,则肯定有Dispose这个方法。但是一个类可以没有Close方法,也可以不叫Close

2、即使像SqlConnection、FileStream这种有Close也有Dispose方法的,IDisposable接口也没有约定Dispose必须帮助Close,只不过一般的Dispose的实现都判断是否Close,如果没有Close则帮助Close,但是这是好心、不是义务

时间: 2024-08-02 02:39:15

【转】.Net高级技术——IDisposable的相关文章

GridView 高级技术

GridView 高级技术 汇总脚注 GridView 的主要目标是显示一组记录,但是你还可以加入一些有趣的信息,如汇总数据.需要如下的操作: 设置 GridView.ShowFooter 为 true ,这样可以显示脚注行(但没有数据) 在 GridView.FooterRow 中加入内容 本例假设正在处理产品列表,一个简单的汇总可以显示产品总价或均价.第一步是确定何时计算这个信息.如果正使用手工绑定(DataSource),那么可以在数据对象绑定到 GridView 之间就读取它的值并进行计

分享Java企业级开发必备高级技术(WebLogic、Tomcat集群,Apach调优)

Java自面世后就非常流行,发展迅速,对C++语言形成有力冲击.在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景,那么滋生的基于java项目也越来越多,对java运行环境的要求也越来越高,很多java的程序员只知道对业务的扩展而不知道对java本身的运行环境的调试,例如虚拟机调优,服务器集群等,所以也滋生本门课程的产生. Java企业级开发必备高级技术(WebLogic.Tomcat集群,Apach调优),刚刚买的,这个教程讲的很好,高清完整版,现低价转两个播放码,可以先

【ASP.NET Identity系列教程(三)】Identity高级技术

注:本文是[ASP.NET Identity系列教程]的第三篇.本系列教程详细.完整.深入地介绍了微软的ASP.NET Identity技术,描述了如何运用ASP.NET Identity实现应用程序的用户管理,以及实现应用程序的认证与授权等相关技术,译者希望本系列教程能成为掌握ASP.NET Identity技术的一份完整而有价值的资料.读者若是能够按照文章的描述,一边阅读.一边实践.一边理解,定能有意想不到的巨大收获!希望本系列博文能够得到广大园友的高度推荐. 15 Advanced ASP

spring(7)spring mvc 的高级技术

[0]README 1)本文部分文字描述转自:"Spring In Action(中/英文版)",旨在review  "spring(7)spring mvc 的高级技术" 的相关知识: 2)本文将会看到如何编写控制器来处理文件上传,如何处理控制器所抛出的异常,以及如何在模型中传递数据,使其能够在重定向之后仍然存活: [1]spring mvc 配置的替代方案 [1.1] 自定义 DispatcherServlet配置 [1.2]添加其他的Servlet 和 Fil

Delphi2010中DataSnap高级技术

Delphi2010中DataSnap高级技术 日期:2010年12月1日 作者:SUNSTONE原创 人气:13498 查看:[大字体 中字体 小字体]  (1)—为DataSnap系统服务程序添加描述 这几天一直在研究Delphi 2010的DataSnap,感觉功能真是很强大,现在足有理由证明Delphi7该下岗了. DataSnap有三种服务模式,其中Service Application方式建立的windows服务没有描述,描述部分是空的,感觉总是欠缺点什么. 现找到办法添加描述: p

.Net高级技术

本次课程中讲的有的东西都是根据初学者的认知规律进行了调整,并不是严谨的,比如很多地方在多AppDomain条件下很多说法就不对了,但是说严谨了大家就晕了,因此继续不严谨的讲吧. 很多面试题都在这阶段的课程中. .Net高级技术属于拔高内容,根据自己的基础决定学习深度. 参考教材: <C#高级编程> <C#图解教程> <CLR Via C#> 正则表达式前奏:地狱 需求1:“192.168.10.5[port=8080]”,这个字符串表示IP地址为192.168.10.5

.net高级技术(class0515)

本次课程中讲的有的东西都是根据初学者的认知规律进行了调整,并不是严谨的,比如很多地方在多AppDomain条件下很多说法就不对了,但是说严谨了大家就晕了,因此继续不严谨的讲吧. 很多面试题都在这阶段的课程中. .Net高级技术属于拔高内容,根据自己的基础决定学习深度. 参考教材: <C#高级编程> <C#图解教程> <CLR Via C#> 正则表达式前奏:地狱 需求1:“192.168.10.5[port=8080]”,这个字符串表示IP地址为192.168.10.5

如鹏网学习笔记(三).Net高级技术

net高级技术 一.多项目开发 1,添加对项目的引用 //新建一个类库,用来放公共的要使用的类,使用的时候别的项目去引用它 //using 类库文件; 注意事项:注意被引用的类要使用public修饰 被引用的程序集中的类的修饰符,如果不写的话,默认是internal. 效果是,只有当前程序集(类库)内部才能访问. 2,多项目时候的配置文件的读取问题 a,只有主项目的配置文件才起作用(当前启动的) b,config文件不能改名,不能建多个config,在config里面也不能建多个AppSetti

【Spring】Spring MVC高级技术

前言 前面学习了简单的Spring Web知识,接着学习更高阶的Web技术. 高级技术 Spring MVC配置的替换方案 自定义DispatcherServlet配置 在第五章我们曾编写过如下代码. public class SpitterWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasse