.NET Dispose模式的实现
以下是代码:
1 using System; 2 /// <summary> 3 /// Dispose Pattern 4 /// </summary> 5 /// <remarks> 6 /// 由逻辑可知: 7 /// 1.不管是手动调用Dispose方法还是系统自动调用析构函数,均会执行【非托管资源】释放程序 8 /// 2.系统自动调用析构函数时,不会执行【托管资源】释放程序 9 /// </remarks> 10 public class DisposableObject : IDisposable 11 { 12 /// <summary> 13 /// 获取或设置一个值。该值指示资源已经被释放。 14 /// </summary> 15 private bool _disposed; 16 17 /// <summary> 18 /// 执行与释放或重置非托管资源相关的应用程序定义的任务。 19 /// </summary> 20 public void Dispose() 21 { 22 Dispose(true); 23 24 // 指示GC不要调用此对象的Finalize方法 25 GC.SuppressFinalize(this); 26 } 27 28 /// <summary> 29 /// 关闭此对象使用的所有资源。 30 /// </summary> 31 /// <remarks> 32 /// 1.有时候特定的名称比Dispose更合适,比如文件封装,网络连接封装等 33 /// 2.此方法不要设计为 virtual,子类不应该重写该方法。 34 /// </remarks> 35 public void Close() 36 { 37 Dispose(); 38 } 39 40 /// <summary> 41 /// 由终结器调用以释放资源。 42 /// </summary> 43 ~DisposableObject() 44 { 45 Dispose(false); 46 } 47 48 public void DoSomething() 49 { 50 if (_disposed) throw new ObjectDisposedException("无法访问已经释放的资源。"); 51 // TODO somethings 52 Console.WriteLine(" >>>>>>>>>>>>> to do somethings...\r\n"); 53 } 54 55 /// <summary> 56 /// 执行与释放或重置非托管资源相关的应用程序定义的任务。 57 /// 派生类中重写此方法时,需要释放派生类中额外使用的资源。 58 /// </summary> 59 protected virtual void Dispose(bool disposing) 60 { 61 if (_disposed) 62 { 63 return; 64 } 65 66 if (disposing) 67 { 68 // TODO 清理托管资源 69 } 70 71 // TODO 1.清理非托管资源 2.将大对象设置为null 72 73 _disposed = true; // 标记已经被释放。 74 } 75 } 76 77 public class Program 78 { 79 public static void Main() 80 { 81 var obj = new DisposableObject(); 82 Console.WriteLine(" >>>>>>>>>>>>> 第一次正常调用...\r\n"); 83 obj.DoSomething(); 84 85 Console.WriteLine(" >>>>>>>>>>>>> 模拟资源释放...\r\n"); 86 // 释放资源 87 obj.Dispose(); 88 Console.WriteLine(" >>>>>>>>>>>>> 资源释放完成...\r\n"); 89 90 Console.WriteLine(" >>>>>>>>>>>>> 再次调用,抛出异常...\r\n"); 91 // 再次调用 92 obj.DoSomething(); 93 } 94 }
运行示例:(你可以编辑框中的代码,体验运行效果)