当前位置: 首页 > news >正文

【转】.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,但是这是好心、不是义务

转载于:https://www.cnblogs.com/janeaiai/p/5015155.html

相关文章:

  • [转]通过脚本添加登陆/注销/开机/关机脚本
  • 学习 AngularJS (三) module
  • Json序列化之.NET开源类库Newtonsoft.Json
  • C/C++ 库函数 是否调用 WinAPI
  • 构造汽车
  • 违反约束或者主外键删除数据
  • 不平衡学习方法理论和实战总结
  • Windows Cygwin Redis 安装(转)
  • apche commons项目简介
  • CAS (2) —— Mac下配置CAS到Tomcat(客户端)
  • Median of Two Sorted Arrays
  • 固态硬盘上安装Windows8(ghost)启动问题
  • 王家林每日大数据语录Spark篇0003
  • [hive小技巧]同一份数据多种处理
  • 【191】◀▶ Powershell 命令集 Cmdlets
  • Android开源项目规范总结
  • C++类的相互关联
  • es6(二):字符串的扩展
  • Java 网络编程(2):UDP 的使用
  • js继承的实现方法
  • opencv python Meanshift 和 Camshift
  • php面试题 汇集2
  • STAR法则
  • uva 10370 Above Average
  • 目录与文件属性:编写ls
  • 思维导图—你不知道的JavaScript中卷
  • 小程序 setData 学问多
  • 小试R空间处理新库sf
  • 学习Vue.js的五个小例子
  • 栈实现走出迷宫(C++)
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • python最赚钱的4个方向,你最心动的是哪个?
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • $jQuery 重写Alert样式方法
  • (7)STL算法之交换赋值
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (java)关于Thread的挂起和恢复
  • (笔试题)合法字符串
  • (多级缓存)多级缓存
  • (附源码)计算机毕业设计高校学生选课系统
  • (七)Knockout 创建自定义绑定
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • (未解决)macOS matplotlib 中文是方框
  • .NET Core MongoDB数据仓储和工作单元模式封装
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .net经典笔试题
  • @Bean有哪些属性
  • @RequestBody与@ResponseBody的使用
  • @SuppressWarnings注解
  • @软考考生,这份软考高分攻略你须知道
  • [ Linux 长征路第二篇] 基本指令head,tail,date,cal,find,grep,zip,tar,bc,unname