有关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

posted @ 2019-08-06 11:32  时空观察者9号  阅读(239)  评论(0编辑  收藏  举报