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 }