这里写自定义目录标题

  • 前言
  • 资源类型
  • 如何释放
  • 为啥必定是Dispose方法?
  • 忘记释放怎么办?
  • 析构函数
  • Dispose模式
  • 对Dispose方法的理解是什么呢?
  • 原理
  • 实例
  • using释放资源
  • 转载

前言

谈到Dispose,首先须要理解C#的资源

资源类型

托管资源:由CLR建立和释放
非托管资源:资源的建立和释放不禁CLR管理。好比IO、网络链接、数据库链接等等。须要开发人员手动释放。

如何释放

调用的是微软类库或者第三方类库,通常类库会提供释放的方法,即约定为Dispose,调用便可。

为啥必定是Dispose方法?

每一个类库固然能够提供各自释放资源的方法,好比close()、close()、release()、clear()等等。网络

但为了统一,微软提供了IDispose接口,其中只声明了一个void的Dispose()方法。并且还为实现了IDispose接口的类提供了using释放资源的语法糖。

namespace System
{[ComVisible(true)]public interface IDisposable{//执行与释放或重置非托管资源关联的应用程序定义的任务。void Dispose();}
}

忘记释放怎么办?

好比咱们进行一个给图片加水印的功能,使用System.Drwing类库中的Image对象。写代码的时候,咱们既不手动调用Dispose方法,也不使用using语法。那么Image对象就一直会留在内存中吗?
固然不会,Image类有析构函数,在其中调用了Dispose方法。

public void Dispose()
{this.Dispose(true);GC.SuppressFinalize(this);
}protected virtual void Dispose(bool disposing)
{if (this.nativeImage != IntPtr.Zero){try{SafeNativeMethods.Gdip.GdipDisposeImage(new HandleRef(this, this.nativeImage));}catch (Exception ex){if (ClientUtils.IsSecurityOrCriticalException(ex)){throw;}}finally{this.nativeImage = IntPtr.Zero;}}
}~Image()
{this.Dispose(false);
}

既然最终析构函数中会释放资源,那么咱们是否是不必手动释放了呢?
这就要说说析构函数了

析构函数

当一个类的实例被GC回收的时候,最终调用的方法。它和构造函数正好相反,后者是在类的实例初始化时调用。线程

它的写法是这样子的:

class Car
{~Car()  // finalizer{// cleanup statements...}
}

隐式的调用了基类的Finalize方法,因此等价下面的写法:

protected override void Finalize()
{  try  {  // Cleanup statements...  }  finally  {  base.Finalize();  }
}

Finalize操做呢,有如下限制:

The exact time when the finalizer executes is undefined.
The finalizers of two objects are not guaranteed to run in any specific order, even if one object refers to the other.
The thread on which the finalizer runs is unspecified.
(来源:https://docs.microsoft.com/en-us/dotnet/api/system.object.finalize?view=netframework-4.8 )

简单理解就是Finalize操做由GC决定,回收的时间不定、顺序不定、线程不定。因此析构函数中调用Dispose只是一个保险措施,并不能代替手动释放资源。

好比数据库链接,你打开链接不及时释放,很快就没法链接新的数据库了。而此时GC有可能还未执行析构函数。

固然,析构函数在GC回收的时候,还会由于垃圾回收机制有其余性能问题,
https://www.cnblogs.com/hetring/p/4755516.html
(参考:https://www.viva64.com/en/b/0437/ )

Dispose模式

因此,到目前为止,咱们清楚的知道,对于非托管资源的使用,必定要记得释放资源。

咱们给被人提供类库的时候,也明白了到底何时须要实现IDispose接口了。

固然,Dispose的实现已然有套路了,称之为Dispose模式,如下是示例:

using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;class BaseClass : IDisposable
{// Flag: Has Dispose already been called?bool disposed = false;// Instantiate a SafeHandle instance.SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);// Public implementation of Dispose pattern callable by consumers.public void Dispose(){ Dispose(true);GC.SuppressFinalize(this);           }// Protected implementation of Dispose pattern.protected virtual void Dispose(bool disposing){if (disposed)return; if (disposing) {handle.Dispose();// Free any other managed objects here.//}disposed = true;}
}

对Dispose方法的理解是什么呢?

使用Dispose方法的对象,应释放它拥有的所有资源。它还应该通过调用其父类型的Dispose方法释放其基类型拥有的所有资源。

.net的对象使用一般分为三种情况﹕

1.创建对象
2.使用对象
3.释放对象

如果是托管堆中申请的对象,垃圾收集器(Garbage Collector)会自动释放对象资源。如果使用非托管(unmanaged)的对象,就要实现IDisposable接口以释放资源。这个类型还必须添加一个作为防御机制的终结器。所有这些程序都把释放资源的工作委托给一个虚拟的方法,衍生的类可以根据自己的资源管理需求来重载该方法。只要衍生的类必须释放自己的资源,并且它必须调用该函数的基类版本的时候,它才需要重载这个虚拟方法。

原理

当垃圾收集器运行的时候,它立即从内存中删除所有不带终结器的垃圾对象。所有带有终结器的对象仍然存在于内存中。这些对象都被添加到终结队列,垃圾收集器引发一个新线程,周期性地在这些对象上运行终结器。在这些终结程序线程完成自己的工作之后,就可以从内存中删除垃圾对象了。需要终结的对象在内存中停留的时间比没有终结器的对象停留的时间长很多。但是你别无选择。如果要使程序有防护性,在类型包含非受控资源的时候,你必须编写一个终结器。但是也不用担心性能问题。下一步确保了客户端避免与终结相关的性能开销。

注:终结器(以前称为析构函数)用于在垃圾回收器收集类实例时执行任何必要的最终清理操作。

实例

public class Foo: IDisposable
{public void Dispose()
{Dispose(true);
GC.SuppressFinalize(this);
}protected virtual void Dispose(bool disposing)
{if (!m_disposed)
{if (disposing)
{// Release managed resources
}// Release unmanaged resourcesm_disposed = true;
}
}~Foo()
{Dispose(false);
}private bool m_disposed;
}

在.NET的对象中实际上有两个用于释放资源的函数:Dispose和Finalize。Finalize的目的是用于释放非托管的资源,而Dispose是用于释放所有资源,包括托管的和非托管的。
原文链接:https://blog.csdn.net/sinat_31608641/article/details/108339273

using释放资源

using 语句允许程序员指定使用资源的对象应当何时释放资源。为 using 语句提供的对象必须实现 IDisposable 接口。此接口提供了 Dispose 方法,该方法将释放此对象的资源。

总而言之,当一个类继承了 IDisposable 接口时,我们尽量要用using或者Dispose函数来手动释放对象的资源。

转载

C#之Dispose相关推荐

  1. RxJava 解除订阅---------Disposable.dispose()方法

    有时候我们需要解绑订阅,或者取消订阅, 这个时候就使用到了 Disposable.dispose()方法下面以一个案例说下使用方法 //Disposable.dispose()切断观察者 与 被观察者 ...

  2. Finalize/Dispose/Destructor

    我总是会搞混这些东西,还是写下来帮助记忆. Finalize 即Object.Finalize(),C#中不允许使用Finalize,析构器就等价于Finalize. Destructor 析构器(D ...

  3. .net内存回收与Dispose﹐Close﹐Finalize方法

    .net内存回收与Dispose﹐Close﹐Finalize方法 一. net的对象使用一般分为三种情况﹕ 1.创建对象 2.使用对象 3.释放对象 二.创建对象 1.创建对象实际分为两个步骤﹕变量 ...

  4. C#中Dispose和Close的区别

    当我们开发C#代码的时候,经常碰到一个问题,有些class提供Close(),有些class提供Dispose(),那么Dispose和Close到底有什么区别? 首先,Dispose和Close基本 ...

  5. C#资源释放及Dispose、Close和析构方法

    C#资源释放及Dispose.Close和析构方法   备注:此文的部分观点有误,之所以仍旧保留本文,是需要在后期给出一个勘误版.正确的版本在这里"C#中标准Dispose模式的实现&quo ...

  6. Effective C# 原则18:实现标准的处理(Dispose)模式(译)

    Effective C# 原则18:实现标准的处理(Dispose)模式 我们已经讨论过,处理一个占用了非托管资源对象是很重要的.现在是时候来讨论如何写代码来管理这些类占用的非内存资源了.一个标准的模 ...

  7. .net中close和dispose及关闭流操作

    之前打开文件流后总不记得关闭流,昨天终于出现问题了,因此上网搜了一下,下面是实际操作和网上搜索后的记录: 1.关闭流的顺序一般为后开先关,如 Image img = Image.FromFile(&q ...

  8. 强制回收和IDisposable.Dispose方法

    如果某对象的 Dispose 方法被调用一次以上,则该对象必须忽略第一次调用后的所有调用. 如果对象的 Dispose 方法被多次调用,该对象一定不要引发异常. 除Dispose 之外的实例方法在资源 ...

  9. 【Flutter】Flutter 页面生命周期 ( 初始化期 | createState | initState | 更新期 | build | 销毁期 | dispose)

    文章目录 一.Flutter 页面生命周期 1.StatelessWidget 组件生命周期函数 2.StatefulWidget 组件生命周期函数 二.StatefulWidget 组件生命周期 1 ...

  10. java中的dispose()方法

    java中的dispose()方法 先来看看 JAVA 1.5 的帮助文档的原文 - dispose - public void dispose() ****** 释放由此 Window.其子组件及其 ...

最新文章

  1. 基于协程的并发框架orchid简介
  2. android 布局: LinearLayout如何使TextView中的内容居中显示
  3. 可执行jar包的MANIFEST.MF
  4. AspectJ 中的pointcut 语法
  5. JavaScript常用单词整理总结
  6. 如何成为一名架构师,架构师成长之路(转)
  7. AARRR:互联网创业者一定要掌握的指标
  8. mybatis 添加语句返回对象_Mybatis底层源码分析
  9. 【学习总结】GirlsInAI ML-diary day-5-布尔表达式/Bool
  10. Atitit 使用js nodejs进行图像处理ocr的解决方案attilax总结
  11. vscode终端中文乱码问题的解决方案合集c++
  12. python数据标注工具_数据标注|分享9个数据标注工具
  13. Lambda 表达式详解
  14. FusionCharts使用实例
  15. PC微信聊天记录数据迁移恢复
  16. Vue - router vs route
  17. 微赞html写入,微赞WZ-后台一键更新-授权
  18. Xcode10打包引起iOS9.0-9.2系统的用户启动App随机崩溃的问题修复记录
  19. 利用Python分析《庆余年》人物图谱和微博传播路径
  20. 数模学习(一)--AHP层次结构法

热门文章

  1. 三维扫描仪中投射模块/投影仪推荐
  2. 逻辑思维与写作-第一章,第二章-随笔笔记
  3. SVG—最简单的SVG动画
  4. Matplotlib:线类型
  5. python画图库哪个好_python常见的十种可视化图库方法展示
  6. GAMIT处理GLONASS数据
  7. 银行卡数据API接口有哪些?
  8. java8中的date和joda time中的日期相互转换
  9. HTML 有序列表 字母,HTML之有序列表教程
  10. win10下载日文输入法时,无法使用日文键盘的问题解决