如果你觉得你的类需要实现 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 模式的实现的更多相关文章

  1. C#中标准Dispose模式的实现与使用(条目17 实现标准的销毁模式)

    实现了Dispose模式与实现了IDisposable接口的区别就是:IDisposable的实现的可靠性(释放相关资源)要靠编程人员来解决(你确信你从来都一直调用了Dispose(Close)方法吗 ...

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

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

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

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

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

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

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

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

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

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

  7. 编写高质量代码改善C#程序的157个建议——建议50:在Dispose模式中应区别对待托管资源和非托管资源

    建议50:在Dispose模式中应区别对待托管资源和非托管资源 真正资源释放代码的那个虚方法是带一个bool参数的,带这个参数,是因为我们在资源释放时要区别对待托管资源和非托管资源. 提供给调用者调用 ...

  8. 编写高质量代码改善C#程序的157个建议——建议49:在Dispose模式中应提取一个受保护的虚方法

    建议49:在Dispose模式中应提取一个受保护的虚方法 在标准的Dispose模式中,真正的IDisposable接口的Dispose方法并没有做实际的清理工作,它其实是调用了下面的这个带bool参 ...

  9. [学习笔记] Dispose模式

    Dispose模式是.NET中很基础也很重要的一个模式,今天重新复习一下相关的东西并记录下来. 什么是Dispose模式? 什么时候我们该为一个类型实现Dispose模式 使用Dispose模式时应该 ...

随机推荐

  1. mac 下 安装 mongodb

    使用brew安装,不过brew不再更新, 通过 sudo chown -R $(whoami):admin /usr/local 这条语句终端有提醒的 xcode-select --install 需 ...

  2. JavaScript清除字符串前后空格

    一.通过循环检查,然后提取非空格字符串 //去掉前后空白 function trim(s){ return trimRight(trimLeft(s)); } //去掉左边的空白 function t ...

  3. Vue 及框架响应式系统原理

    个人bolg地址 全局概览 Vue运行内部运行机制 总览图: 初始化及挂载 在 new Vue()之后. Vue 会调用 _init 函数进行初始化,也就是这里的 init 过程,它会初始化生命周期. ...

  4. FlexboxLayout——Android弹性布局

    FlexboxLayout是一个Android平台上与CSS的 Flexible box 弹性盒子布局模块 有相似功能的库.Flexbox 是CSS 的一种布局方案,可以简单.快捷的实现复杂布局. F ...

  5. rabbitmq&&erlang 安装

    # yum install epel-release CentOS and Red Hat Enterprise Linux 6.x wget https://dl.fedoraproject.org ...

  6. 【Raspberry pi】cpu、内存等查看及扩展

    使用树莓派时,需要在其系统中部署几个不同功能的程序系统,并涉及到数据库读写.串口读写.web访问等,使系统使用压力较大,在查看树莓派使用情况时也遇到些许问题. free命令 total used fr ...

  7. Hugepages,hugetlb_shm_group与ORA-27125

    Hugepages,hugetlb_shm_group与ORA-27125 转载:http://www.eygle.com/archives/2011/12/hugepageshugetl.html ...

  8. 【待填坑】ajax问题

    原生xhr怎么写? 怎么处理回调? 问:http状态码常见有哪些? 问:302是啥?304是啥?什么时候会返回304?你刚刚说浏览器缓存,具体缓存机制是怎么样的? 问:你刚刚说的是发起一个get请求, ...

  9. p标签多行文字内容实现上下垂直居中兼容ie8

    之前实现上下居中一般都是用height和line-height的来设置. 今天在修改样式的时候,p标签的文字内容可能是一行也可能是两行, 所以用height和line-height就没效果. 今天找到 ...

  10. CF 187C Weak Memory 优先队列 难度:2

    http://codeforces.com/problemset/problem/187/C 这道题可以用二分+dfs检测,或者优先队列解 此处用了优先队列解法 从起点出发,维护一个优先队列,内容是p ...