C#中标准Dispose模式的实现与使用(条目17 实现标准的销毁模式)
实现了Dispose模式与实现了IDisposable接口的区别就是:IDisposable的实现的可靠性(释放相关资源)要靠编程人员来解决(你确信你从来都一直调用了Dispose(Close)方法吗?),而实现了Dispose模式后,当编程人员没有主动调用Dispose方法时,会由终结器来调用(有些时候编程人员想主动调用也调用不了,比如远程连上来的TcpChannel,客户端断开时,服务端只能由终者器调用)。
Dispose模式()的实现需要以下4个步骤:
1. 释放所有非托管资源;
2. 释放所有托管资源,包括释放事件监听程序;
3. 设计一个状态标志(IsDisposed),表示该对像已经被销毁。若是在销毁后再次调用对像的公有方法,那么应该抛出ObjectDisposed异常;
4. 跳过终者操作,调用CG.SuppressFinalize(this)即可。
注:
------------------
托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象;
非托管资源:不受CLR管理的对象,windows内核对象,如文件、数据库连接、套接字、COM对象等;
用实现来说明。
EXAMPLE CODE:
using System; namespace CS.DesignPatterns
{
/// <summary>
/// 示例
/// </summary>
public class DisposePatternSample:IDisposable
{
private bool _isDisposed;//是否已释放了资源,true时方法都不可用了。 public DisposePatternSample()
{
_isDisposed = false;
} public void MethodSample()
{
if(_isDisposed)
throw new ObjectDisposedException("inner resource is disposed.");
Console.WriteLine("MethodSample is called.");
} /// <summary>
/// 为继承类释放时使用
/// <remarks>
/// Note:这儿为什么要写成虚方法呢?
/// 1. 为了让派生类清理自已的资源。将销毁和析构的共同工作提取出来,并让派生类也可以释放其自已分配的资源。
/// 2. 为派生类提供了根据Dispose()或终结器的需要进行资源清理的必要入口。
/// </remarks>
/// </summary>
/// <param name="isDisposing"></param>
protected virtual void Dispose(bool isDisposing)
{
if(_isDisposed)return; if (isDisposing)
{
//释放托管资源
//(由CLR管理分配和释放的资源,即由CLR里new出来的对象)
//TODO: other code
} //释放非托管资源
//(不受CLR管理的对象,windows内核对象,如文件、数据库连接、套接字、COM对象等)
//TODO: other code _isDisposed = true;
} #region IDisposable 成员 public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} #endregion ///// <summary>
///// 如果没有非托管资源,不要实现它
///// </summary>
//~DisposePatternSample()
//{
// Dispose(false);
//}
} public class DrivedDisposePatternSample : DisposePatternSample
{
private bool _isDisposed = false; //各类维护自已的释放状态,把可能出现的错误限制在类本身 /// <summary>
/// 子类清理自已的资源时使用
/// </summary>
/// <param name="isDisposing"></param>
protected override void Dispose(bool isDisposing)
{
if(_isDisposed)return;
if (isDisposing)
{
//释放托管资源
//(由CLR管理分配和释放的资源,即由CLR里new出来的对象)
//TODO: other code
} //释放非托管资源
//(不受CLR管理的对象,windows内核对象,如文件、数据库连接、套接字、COM对象等)
//TODO: other code //基类释放资源
//基类负责调用GC.SuppressFinalize()
base.Dispose(isDisposing); _isDisposed = true;
} ///// <summary>
///// 如果没有非托管资源,不要实现它
///// </summary>
//~DrivedDisposePatternSample()
//{
// Dispose(false);
//} } }
上述的代码并没有使用析构方法,这是因为上述的代码并没有使有非托管资源(永远不会调用Dispose(false))方法。注意:除非你调用了非托管资源,否则不要实现析构方法。即使析构器永远不会被调用,它本身也会极大的影响类型的性能。不要画蛇添足。不过这个模式却不能改变,因为你的派生类可能会用到非托管的资源。
重要的建议:只能在Dispose方法中释放资源,不得进行其它操作(如果一不小心的其它操作,让本该死亡的对象起死回生,哼哼~~~~)。
请遵守Dispose标准模式的实现,这会节省你,你的类型使用者,你的类型的派生者的大量的时间。
C#中标准Dispose模式的实现与使用(条目17 实现标准的销毁模式)的更多相关文章
- C#中标准Dispose模式的实现
http://www.cnblogs.com/luminji/archive/2011/03/29/1997812.html 需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个 ...
- [No000017B]改善C#程序的建议4:C#中标准Dispose模式的实现
需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:不 ...
- [转]改善C#程序的建议4:C#中标准Dispose模式的实现
需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:不 ...
- 改善C#程序的建议4:C#中标准Dispose模式的实现
http://www.cnblogs.com/luminji/archive/2011/03/29/1997812.html 需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个 ...
- C#中标准Dispose模式的实现(转载)
需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:w ...
- C#的内存管理原理解析+标准Dispose模式的实现
本文内容是本人参考多本经典C#书籍和一些前辈的博文做的总结 尽管.NET运行库负责处理大部分内存管理工作,但C#程序员仍然必须理解内存管理的工作原理,了解如何高效地处理非托管的资源,才能在非常注重性能 ...
- 标准Dispose实现 (转)
需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源 ...
- 16位模式/32位模式下PUSH指令探究——《x86汇编语言:从实模式到保护模式》读书笔记16
一.Intel 32 位处理器的工作模式 如上图所示,Intel 32 位处理器有3种工作模式. (1)实模式:工作方式相当于一个8086 (2)保护模式:提供支持多任务环境的工作方式,建立保护机制 ...
- C 和 C++ 的标准库分别有自己的 locale 操作方法,C 标准库的 locale 设定函数是 setlocale(),而 C++ 标准库有 locale 类和流对象的 imbue() 方法(gcc使用zh_CN.GBK,或者zh_CN.UTF-8,VC++使用Chinese_People's Republic of China.936或者65001.)
转自:http://zyxhome.org/wp/cc-prog-lang/c-stdlib-setlocale-usage-note/ [在此向原文作者说声谢谢!若有读者看到文章转载时请写该转载地址 ...
随机推荐
- java枚举与.net中的枚举区别
通过一段时间的项目实践,发现java中的枚举与.net中的枚举有很大的差别,初期造成了我对java中的枚举一些错误理解及部分有缺陷的应用,其实追其原因还是因为我会习惯性的认为java的枚举在作用以及定 ...
- ASP.NET MVC Model绑定的简单应用
Model绑定是 MVC 框架根据 HTTP 请求数据创建 .NET 对象的一个过程. 一.简单类型 1.单一值
- SubSonic2.2框架的使用方法和配置说明
网上.net ORM框架也不少,但是我感觉这个框架配置很简单的,前几年貌似用的人很多,现在好像用得比较少了,随着它官方的升级现在已经到3.0了, 并且采用T4 模板生成的方式,代码量好像减少了.不过我 ...
- CSS3绘制六边形
因为很简单,所以先总结一下:使用CSS3绘制六边形主要使用伪类:before和:after在源元素之前和之后再绘制两个元素,并利用css3的边框样式,将这两个元素变成三角形放置在源元素的两端即可. ( ...
- ADFS 登录页面自定义
https://blogs.technet.microsoft.com/pie/2015/08/29/customizing-the-ad-fs-sign-in-pages-per-relying-p ...
- sharepoint 权限继承相关
重新继承父级权限: SPList.ResetRoleInheritance(); 断开继承: SPList.BreakRoleInheritance(true); 用powershell断开继承: $ ...
- OC中的深拷贝与浅拷贝
深拷贝(deep copy)与浅拷贝(shallow copy)的定义一直是有争论的. 一种理解是: 所谓的浅拷贝, 就是不完全的拷贝 NSString *s = @"123"; ...
- Source Insight基本使用和快捷键
Source Insight基本使用和快捷键 为什么要用Source Insight呢?貌似是因为比完整的IDE要更快一些,比较利于查看大量的代码. 软件的安装很简单,设置好安装目录. 配置好文档路径 ...
- [Android]proguard重新编译和如何不混淆第三方jar包
转载自:http://glblong.blog.51cto.com/3058613/1536516 一.ant安装.环境变量配置及验证 (一)安装ant 到官方主页http://ant.apache. ...
- 小试SQL SERVER 2014 加密备份
数据库加密: http://blog.csdn.net/u012992506/article/details/25283035 create master key encrypti ...