有关Dispose,Finalize,GC.SupressFinalize函数-托管与非托管资源释放的模式
//这段代码来自官方示例,删除了其中用处不大的细节
using System;
using System.ComponentModel; /***
* 这个模式搞的这么复杂,目的是:不管使用者有没有手动调用Dipose函数,都能保证托管资源被正确释放,但非托管资源不管,因为非托管资源只能由用户保证
* 1,若用户手动调用Dispose(),则Dipose(true)被调用,托管与非托管一起释放了,同时告诉GC不要再执行析构函数
* 2,若用户没有手动调用Dispose()函数,则析构函数最终会被执行,其中调用了Dipose(false),保证托管资源被释放
*/
public class ConsoleMonitor : IDisposable
{
private bool disposed = false;
public ConsoleMonitor()
{
Console.WriteLine("The ConsoleMonitor class constructor.\n");
} // The destructor calls Object.Finalize.
~ConsoleMonitor()
{
Console.WriteLine("The ConsoleMonitor finalizer.\n"); // Call Dispose with disposing = false.
Dispose(false);
} public void Write()
{
Console.WriteLine("The Write method.\n");
} /***
* 不要写这个方法,会报错,因为它有BUG,很容易出错,官方推荐方式是用析构函数来替代此方法
* 原理上来说,此方法是继承了IDispose的类在析构时会被调用的,它最初的设计目的等同于析构函数
*/
//void Finalize()
//{ //} //给外部手动调用的,方法名可以任意
public void Dispose()
{
Console.WriteLine("TThe Dispose method.\n"); Dispose(true); //告诉GC管理器,当GC执行时不要再调用此对象的析构函数(其中有Dispose(false)),因为我们自己已在Dispose(true)中已进行了dipose(false)的操作
GC.SuppressFinalize(this);
} /***给析构函数(或finalize)调用的,函数签名必须这样
* 注意finalize已废弃,见如上说明
* disposing:当我们自己调用时传true,当系统调用时为false
* true和false主要为了区别销毁托管资源与非托管资源
*/
private void Dispose(bool disposing)
{
Console.WriteLine("The Dispose({0}) method.\n"); // Execute if resources have not already been disposed.
if (!disposed)
{
// If the call is from Dispose, free managed resources.
if (disposing)
{
Console.Error.WriteLine("Disposing of managed resources.");
}
// Free unmanaged resources.
Console.WriteLine("Disposing of unmanaged resources.");
}
disposed = true;
}
} public class Example
{
public static void Main()
{
Console.WriteLine("ConsoleMonitor instance....");
ConsoleMonitor monitor = new ConsoleMonitor();
monitor.Write();
monitor.Dispose();
}
}
// If the monitor.Dispose method is not called, the example displays the following output:
// ConsoleMonitor instance....
// The ConsoleMonitor class constructor.
// The Write method.
// The ConsoleMonitor finalizer.
// The Dispose(False) method.
// Disposing of unmanaged resources.
//
// If the monitor.Dispose method is called, the example displays the following output:
// ConsoleMonitor instance....
// The ConsoleMonitor class constructor.
// The Write method.
// The Dispose method.
// The Dispose(True) method.
// Disposing of managed resources.
// Disposing of unmanaged resources.
具体理论参考官方解析:
Implementing a Dispose method
有关Dispose,Finalize,GC.SupressFinalize函数-托管与非托管资源释放的模式的更多相关文章
- C#中Dispose,finalize,GC,析构函数区别
释放类所使用的未托管资源的两种方式: 1.利用运行库强制执行的析构函数,但析构函数的执行是不确定的,而且,由于垃圾收集器的工作方式,它会给运行库增加不可接受的系统开销. 2.IDisposable接 ...
- [.net 面向对象程序设计进阶] (8) 托管与非托管
本节导读:虽然在.NET编程过程中,绝大多数内存垃圾回收由CLR(公共语言运行时)自动回收,但也有很多需要我们编码回收.掌握托管与非托管的基本知识,可以有效避免某些情况下导致的程序异常. 1.什么是托 ...
- C# using 三种使用方式 C#中托管与非托管 C#托管资源和非托管资源区别
1.using指令.using + 命名空间名字,这样可以在程序中直接用命令空间中的类型,而不必指定类型的详细命名空间,类似于Java的import,这个功能也是最常用的,几乎每个cs的程序都会用到. ...
- C#的托管与非托管大难点
托管代码与非托管代码 众所周知,我们正常编程所用的高级语言,是无法被计算机识别的.需要先将高级语言翻译为机器语言,才能被机器理解和运行.在标准C/C++中,编译过程是这样的:源代码首先经过预处理器,对 ...
- C#的三大难点之二:托管与非托管
相关文章: C#的三大难点之前传:什么时候应该使用C#?C#的三大难点之一:byte与char,string与StringBuilderC#的三大难点之二:托管与非托管C#的三大难点之三:消息与事件 ...
- C# 托管和非托管混合编程
在非托管模块中实现你比较重要的算法,然后通过 CLR 的平台互操作,来使托管代码调用它,这样程序仍然能够正常工作,但对非托管的本地代码进行反编译,就很困难. 最直接的实现托管与非托管编程的方法就是 ...
- NET的堆和栈04,对托管和非托管资源的垃圾回收以及内存分配
在" .NET的堆和栈01,基本概念.值类型内存分配"中,了解了"堆"和"栈"的基本概念,以及值类型的内存分配.我们知道:当执行一个方法的时 ...
- [转]C# 之DLL调用(托管与非托管)
每种编程语言调用DLL的方法都不尽相同,在此只对用C#调用DLL的方法进行介绍.首先,您需要了解什么是托管,什么是非托管.一般可以认为:非托管代码主要是基于win 32平台开发的DLL,activeX ...
- Oracle Data Provider for .NET的使用(托管与非托管(一))
目录 简单的概述 简单的使用 非托管系统要求 托管驱动系统要求 其它的注意事项 ODP.NET版本说明 安装ODP.NET 安装非托管驱动 非托管驱动绿色配置 简单的概述 ODP.NET的含义是 Or ...
随机推荐
- The Frog's Games
The Frog's Games Problem Description The annual Games in frogs' kingdom started again. The most famo ...
- uboot启动第一阶段分析
一. uboot第一阶段初识 1.1. 什么是uboot第一阶段 1.1.1. 启动os三个阶段 1.1.1.1. bl0阶段 a. 这段代码是三星固化到iROM中,可以查看<S5PV210_i ...
- kotlin学习(9)注解
我们一般使用类和函数要说明类和函数的确切名称.调用一个类,你需要知道它定义在哪个类中,还有它的名称和参数的类型. 注解和反射可以给你超越这个规则的能力,让你编写出使用事先未知的任意类的代码.注解赋予这 ...
- 为什么要用消息队列 及 自己如何设计一个mq架构
1. 解耦:如左图, 系统a因为业务需求需要调用系统b,后续因为业务需求可能需要改代码调用系统c,甚至还要考虑被调用的系统挂了访问超时的问题.耦合性太高! 如右图, 系统a产生一条数据发送到消息队列里 ...
- 剑指offer-二叉搜索树的第k个结点树-python
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的 ...
- mailstats - 显示邮件状态信息
总览 mailstats [-o] [-C cffile] [-f stfile] 描述 mailstats工具显示当前的邮件状态信息. 首先,先显示统计启动时所记录的时间,当然是以ctime(3)所 ...
- Python核心技术与实战——五|条件与循环
我们在前面学习了列表.元组.字典.集合和字符串等一系列Python的基本数据结构类型,下就需要把这一个个基本的数据串在一起了,这就要用到我们今天要讲的东西——”条件与循环“. 一.条件语句 条件语句的 ...
- <转>ThinkPHP的开发常用系统配置项
/* 项目设定 */ ’APP_DEBUG’ => false, // 是否开启调试模式 ’APP_DOMAIN_DEPLOY’ => false, // 是否使用独立域名部署项目 ’AP ...
- java.sql.SQLException: Unknown system variable 'query_cache_size'
改为 <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java< ...
- Python(1) 整型与浮动型
整型与浮动型 整数/浮动数=浮点型整数/整数 = 浮点型 例如:>>> type(1/1)<class 'float'>>>> type(1/1.0)& ...