有关Dispose,Finalize,GC.SupressFinalize函数-托管与非托管资源释放的模式

时间:2024-07-31 19:33:56
//这段代码来自官方示例,删除了其中用处不大的细节
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