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清除:收尾和垃圾收集
垃圾收收集器(GC)只知道释放由new关键字分配的内存,所以不知道如何释放对象的"特殊"内存.为了解决这个问题,Java提供了一个名为:finalize()的方法,可为我们的类定义 ...
- INFO: task java:27465 blocked for more than 120 seconds不一定是cache太大的问题
这几天,老有几个环境在中午收盘后者下午收盘后那一会儿,系统打不开,然后过了一会儿,进程就消失不见了,查看了下/var/log/message,有如下信息: Dec 12 11:35:38 iZ23nn ...
- SQL SERVER 2008 R2 SP1更新时,遇上共享功能更新失败解决方案
SQL SERVER 2008 R2 SP1更新时,遇上共享功能更新失败的问题,可作如下尝试: 更新失败后,在windows的[事件查看器→应用程序]中找到来源为MsiInstaller,事件ID为1 ...
- mongodb 查询的用法
想要在C#中使用MongoDB,首先得要有个MongoDB支持的C#版的驱动.C#版的驱动貌似有很多种,如官方提供的samus. 实现思路大都类似.这里我们用官方提供的mongo-csharp-dri ...
- 如何在silverlight中以同步方式 获取sharepoint2013站点的当前登录账号
最近有个项目用到了silverlight要同步方式获取当前登录账号.异步的方式无法跟其他应用结合.主要先后顺序问题.但是silverlight非常不好获取到当前登录账号.即使获取到了也是异步方式获取. ...
- disable-the-loopback-check-for-specific-host-names-on-all-sharepoint-web-and-application-servers/
Microsoft has introduced new feature – Loopback Security Check in Windows Server 2003 SP1 to prevent ...
- OC笔记
self的概念:指向了当前对象(方法的调用者) self的用途 可以利用 self -> 成员变量名 访问当前对象内部的成员变量 [self 方法名]; 调用其他对象方法或者类方法 所有继 ...
- Android读取自定义View属性
Android读取自定义View属性 attrs.xml : <?xml version="1.0" encoding="utf-8"?> < ...
- 【代码笔记】iOS-离线地图
一,效果图. 二,工程图. 三,代码. ViewController.h #import <UIKit/UIKit.h> #import <CoreLocation/CoreLoca ...
- 【代码笔记】iOS-剧幕拉开形的首页
一,工程图. 二,代码. RootViewController.h #import <UIKit/UIKit.h> #import "UIImage+SplitImageInto ...