C#/.NET 中推荐的 Dispose 模式的实现
如果你觉得你的类需要实现 IDisposable 接口,还是需要注意一些坑的。不过前人准备了 Dispose 模式 供我们参考,最大程度避免这样的坑。
C#程序中的 Dispose 方法,一旦被调用了该方法的对象,虽然还没有垃圾回收,但实际上已经不能再使用了。所以使用上要仔细考虑细节。
需要明确一下 C# 程序(或者说 .NET)中的资源。简单的说来,C# 中的每一个类型都代表一种资源,而资源又分为两类:
- 托管资源:由 CLR 管理分配和释放的资源,即由 CLR 里 new 出来的对象;
- 非托管资源:不受 CLR 管理的对象,Windows 内核对象,如文件、数据库连接、套接字、COM 对象等;
毫无例外地,如果我们的类型使用到了非托管资源,或者需要显式释放的托管资源,那么,就需要让类型继承接口 IDisposable。这相当于是告诉调用者,该类型是需要显式释放资源的,你需要调用我的 Dispose 方法。
不过,这一切并不这么简单,一个标准的继承了 IDisposable 接口的类型应该像下面这样去实现。这种实现我们称之为 Dispose 模式:
public class DisposableObject : IDisposable
{
/// <summary>
/// 获取或设置一个值。该值指示资源已经被释放。
/// </summary>
private bool _disposed;
/// <summary>
/// 执行与释放或重置非托管资源相关的应用程序定义的任务。
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// 关闭此对象使用的所有资源。
/// </summary>
public void Close()
{
Dispose();
}
/// <summary>
/// 由终结器调用以释放资源。
/// </summary>
~DisposableObject()
{
Dispose(false);
}
/// <summary>
/// 执行与释放或重置非托管资源相关的应用程序定义的任务。
/// 派生类中重写此方法时,需要释放派生类中额外使用的资源。
/// </summary>
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
// 清理托管资源
// if (managedResource != null)
// {
// managedResource.Dispose();
// managedResource = null;
// }
}
// 清理非托管资源
// if (nativeResource != IntPtr.Zero)
// {
// Marshal.FreeHGlobal(nativeResource);
// nativeResource = IntPtr.Zero;
// }
// 标记已经被释放。
_disposed = true;
}
}
C#/.NET 中推荐的 Dispose 模式的实现的更多相关文章
- C#中标准Dispose模式的实现与使用(条目17 实现标准的销毁模式)
实现了Dispose模式与实现了IDisposable接口的区别就是:IDisposable的实现的可靠性(释放相关资源)要靠编程人员来解决(你确信你从来都一直调用了Dispose(Close)方法吗 ...
- 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#程序的157个建议——建议50:在Dispose模式中应区别对待托管资源和非托管资源
建议50:在Dispose模式中应区别对待托管资源和非托管资源 真正资源释放代码的那个虚方法是带一个bool参数的,带这个参数,是因为我们在资源释放时要区别对待托管资源和非托管资源. 提供给调用者调用 ...
- 编写高质量代码改善C#程序的157个建议——建议49:在Dispose模式中应提取一个受保护的虚方法
建议49:在Dispose模式中应提取一个受保护的虚方法 在标准的Dispose模式中,真正的IDisposable接口的Dispose方法并没有做实际的清理工作,它其实是调用了下面的这个带bool参 ...
- [学习笔记] Dispose模式
Dispose模式是.NET中很基础也很重要的一个模式,今天重新复习一下相关的东西并记录下来. 什么是Dispose模式? 什么时候我们该为一个类型实现Dispose模式 使用Dispose模式时应该 ...
随机推荐
- Quartz(自动任务)中的触发器Trigger
1.Quartz中的触发器TriggerJob 包含了要执行任务的逻辑,但是 Job 对何时该执行却一无所知.这个事情留给了 Trigger.Quartz Trigger 继承了抽象的 org.qua ...
- 修改sublime侧边栏的颜色
Ctrl+Shift+P -> install -> 搜索安装包SyncedSidebarBg,自动同步侧边栏底色为编辑窗口底色.
- 如何调试nRF5 SDK
本文将讲述Nordic nRF5 SDK的主要调试手段,以帮助大家快速定位问题,并解决问题.一般来说,你可以通过打log方式,IDE的debug模式,SDK自带的app_error_check函数,以 ...
- http协议报头详解
目录: 1. http协议简介 2. http报头举例 3. http报头详解 4. 几个字段的说明 5. 总结 6. 参考文章 1. http协议简介 HTTP是Hyper Text Transfe ...
- 获得Python脚本所在目录
如何获得Python脚本所在目录的位置 On this page... (hide) 1. 以前的方法 2. 正确的方法 3. 实例说明 (Edit) 1. 以前的方法 如果是要获得程 ...
- java开发中的重中之重-------mysql(基础篇)
介绍: mysql是目前世界上最流行的关系型数据库,在国内大的互联网公司都在使用mysql数据库,mysql经常被我们这样概述,“mysql是轻量级关系型数据库”,其实轻量级并不是说mysql是中小型 ...
- SPOJ-394-ACODE - Alphacode / dp
ACODE - Alphacode #dynamic-programming Alice and Bob need to send secret messages to each other and ...
- IOS - 前台时的推送弹窗效果
作者:Pikacode 原文链接:http://www.jianshu.com/p/67864e1c2085 本文获作者授权转载 或许很多童鞋还不知道,在 iOS 中收到推送通知时,如果 App 处于 ...
- 几款必备LINUX的命令行神器
Dstat & sar iostat, vmstat, ifstat 三合一的工具,用来查看系统性能(我在<性能调优攻略>中提到过那三个xxstat工具). 官方网站:http:/ ...
- 【Error】 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
mysql 登录输入密码有时会碰到如题的错误. 错误描述: Error 1045 (28000): Access denied for user 'root'@'localhost' (using p ...