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/ [在此向原文作者说声谢谢!若有读者看到文章转载时请写该转载地址 ...
随机推荐
- MongoDB常用操作--数据库
1.查看所有数据库,使用命令 show dbs 2.查看当前所在数据库,使用命令 db 3. 查看当前数据库中所有的集合,使用命令 show collections 或使用show tables 4. ...
- 原博客地址http://blog.chinaunix.net/uid/20656672.html弃用
原博客地址http://blog.chinaunix.net/uid/20656672.html弃用
- python数据类型详解及列表字典集合推导式详解
一.运算符 Python语言支持以下类型的运算符: 算术运算符 如: #!/usr/bin/env python # -*- coding:utf-8 -*- a = 5 b = 6 print(a ...
- 设计模式——Spring IoC中用到的模板方法模式
基本概念 什么是模板方法(Template method):父类定义了骨架(调用哪些方法及顺序),某些特定方法由子类实现. 最大的好处:代码复用,减少重复代码.除了子类要实现的特定方法,其他方法及方法 ...
- ScrollReveal.js – 帮助你实现超炫的元素运动效果
ScrollReveal.js 用于创建和管理元素进入可视区域时的动画效果,帮助你的网站增加吸引力.只需要给元素增加 data-scrollreveal 属性,当元素进入可视区域的时候会自动被触发设置 ...
- input输入样式,动画
模板描述:input输入样式 动画,有输入框也有搜索框的样式,多种多样,大家根据自己的喜欢来. 找网站SEO教程,网站模板,以及想要建立个人博客的朋友来涂志海个人博客网,这里有你想要的一切(万一没有的 ...
- Egret白鹭H5小游戏开发入门(三)
前言: 在上一篇文章中着重介绍了H5小游戏开发的起步阶段,如Wing面板的使用,素材的处理,类的说明等等,那么今天主要是涉及到场景的创建,loading的修改等等的代码编写. 对于这一节,我在讲解的过 ...
- ArcPy之Python介绍
1.Python简介 Python是一种面向对象.解释型计算机程序设计语言;Python是一种简单易学,功能强大的编程语言.它有高效率的高层数据结构,简单而有效地实现面向对象编程.Python简洁的语 ...
- R语言学习
1.清屏 Ctrl + L 2.退出 q() 3.设置工作空间 getwd() setwd('D:\\Program Files\\RStudio\\workspace') 4.显档当前工作目录下的文 ...
- Servlet基础(二) Servlet的生命周期
Servlet基础(二) Servlet的生命周期 Servlet的生命周期可以分为三个阶段: 1.初始化阶段 2.响应客户请求阶段 3.终止阶段 Servlet的初始化阶段 在下列时刻Servlet ...