实现了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 实现标准的销毁模式)的更多相关文章

  1. C#中标准Dispose模式的实现

    http://www.cnblogs.com/luminji/archive/2011/03/29/1997812.html 需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个 ...

  2. [No000017B]改善C#程序的建议4:C#中标准Dispose模式的实现

    需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:不 ...

  3. [转]改善C#程序的建议4:C#中标准Dispose模式的实现

    需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:不 ...

  4. 改善C#程序的建议4:C#中标准Dispose模式的实现

    http://www.cnblogs.com/luminji/archive/2011/03/29/1997812.html 需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个 ...

  5. C#中标准Dispose模式的实现(转载)

    需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:w ...

  6. C#的内存管理原理解析+标准Dispose模式的实现

    本文内容是本人参考多本经典C#书籍和一些前辈的博文做的总结 尽管.NET运行库负责处理大部分内存管理工作,但C#程序员仍然必须理解内存管理的工作原理,了解如何高效地处理非托管的资源,才能在非常注重性能 ...

  7. 标准Dispose实现 (转)

      需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源 ...

  8. 16位模式/32位模式下PUSH指令探究——《x86汇编语言:从实模式到保护模式》读书笔记16

    一.Intel 32 位处理器的工作模式 如上图所示,Intel 32 位处理器有3种工作模式. (1)实模式:工作方式相当于一个8086 (2)保护模式:提供支持多任务环境的工作方式,建立保护机制 ...

  9. 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/ [在此向原文作者说声谢谢!若有读者看到文章转载时请写该转载地址 ...

随机推荐

  1. 使用mysql的长连接

    有个资料看得我云里雾里的.现在用自己的言语来总结一下,写文字,能够加深自己的理解.也会在写的过程中帮助自己发现理解方面瑕疵,继续查资料求证. 短链接的缺点:创建一个连接,程序执行完毕后,就会自动断掉与 ...

  2. Java 经典实例: Unicode字符和String之间的转换

    在Java诞生之际,Unicode码是一个16位的字符集,因此char值似乎顺其自然为16位宽,多年来一个char变量几乎可以表示任何Unicode字符. /** * Created by Frank ...

  3. Uploadify 上传插件引起Chrome崩溃解决方法

    将Uploadify初始化代码延时加载,可解决Chrome崩溃. setTimeout(initUploadify, 60); function initUploadify() { var $Uplo ...

  4. 变量作用域&函数作用域

    一. 变量作用域 1)全局变量 在全局环境下声明的变量被视为全局变量. 在没有使用var进行声明的时候,变量就被定义为全局变量.在ES5的严格模式下,如果变量没有使用var来声明是会报错的. 2)局部 ...

  5. MSCRM 报表显示 rsprocessingaborted 错误

    今天又有朋友遇到rsprocessingaborted这个问题,想想这个已经是很老很老的问题了,得在写一遍补充下. 一.首先会考虑是不是SrsDataConnector没有安装的原因,如果正常安装的话 ...

  6. DevExpress v15.2.4帮助文档下载(全)

    原文地址:http://www.devexpresscn.com/Resources/Documentation-498.html DevExpress v15.2帮助文档下载列表大全来啦!包含.ne ...

  7. mysql 数据库服务中的应用程序

    mysql 是一个数据库服务,而实现数据库服务是由mysql中的很多子应用程序来完成的(http://dev.mysql.com/doc/refman/5.7/en/programs-overview ...

  8. ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局

    本文转自 :http://www.cnblogs.com/wendingding/p/3761730.html ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布 ...

  9. 浅析Dagger2的使用

    什么是Dagger2 Dagger是为Android和Java平台提供的一个完全静态的,在编译时进行依赖注入的框架,原来是由Square公司维护,现在由Google维护. 我们知道Dagger是一个依 ...

  10. ios 友盟第三方登录遇到的各种坑。

    //未使用pod的点友盟官方文档 http://dev.umeng.com/social/ios/quick-integration 首先pod导入 pod 'UMengSocialCOM', '~& ...