1.Dispose方法中,应该使用GC.SuppressFinalize防止GC调用Finalize方法,因为显示调用Dispose比较好。
2.Disposed字段保证了两次调用Dispose方法不会抛出异常。
3.同时实现Finalize方式和Dispose方式,一方面Dispose方法可以克服Finalize方法在性能上的弊端;另一方面,Finalize方法又能确保没有显式调用Dispose方法时,也自行回收使用的所有资源。
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace DisposeAndFinalize { class FileDealer:IDisposable { //定义一个访问文件资源的Win32句柄 private IntPtr fileHandle; //定义应用的托管资源 private ManagedRes managedRes; //标记dispose是否已被调用 private bool Disposed = false; //定义构造器,初始化托管资源和非托管资源 public FileDealer(IntPtr handle,ManagedRes res) { fileHandle = handle; managedRes = res; } //实现终结器,定义Finalize ~FileDealer() { if (fileHandle != IntPtr.Zero) { Dispose(false); } } //实现IDisposable接口 public void Dispose() { Dispose(true); //阻止GC调用Finalize方法 GC.SuppressFinalize(this); } //实现一个处理资源清理的具体方法 protected virtual void Dispose(bool disposing) { if(!Disposed ) { if (disposing) { //清理托管资源 managedRes.Dispose(); } //执行资源清理,在此为关闭对象句柄 if(fileHandle!=IntPtr.Zero) { CloseHandle(fileHandle); fileHandle = IntPtr.Zero; } } Disposed = true; } public void Close() { //在内部调用Dispose来实现 Dispose(); } //实现对文件句柄的其他应用方法 public void Write() { } public void Read() { } //引入外部Win32API [DllImport("Kernel32")] private extern static Boolean CloseHandle(IntPtr handle); } }