1 /// <summary>
2 /// Dispose Pattern
3 /// </summary>
4 /// <remarks>
5 /// 由逻辑可知:
6 /// 1.不管是手动调用Dispose方法还是系统自动调用析构函数,均会执行【非托管资源】释放程序
7 /// 2.系统自动调用析构函数时,不会执行【托管资源】释放程序
8 /// </remarks>
9 public class DisposableObject : IDisposable
10 {
11 /// <summary>
12 /// 获取或设置一个值。该值指示资源已经被释放。
13 /// </summary>
14 private bool _disposed;
15
16 /// <summary>
17 /// 执行与释放或重置非托管资源相关的应用程序定义的任务。
18 /// </summary>
19 public void Dispose()
20 {
21 Dispose(true);
22
23 // 指示GC不要调用此对象的Finalize方法
24 GC.SuppressFinalize(this);
25 }
26
27 /// <summary>
28 /// 关闭此对象使用的所有资源。
29 /// </summary>
30 /// <remarks>
31 /// 1.有时候特定的名称比Dispose更合适,比如文件封装,网络连接封装等
32 /// 2.此方法不要设计为 virtual,子类不应该重写该方法。
33 /// </remarks>
34 public void Close()
35 {
36 Dispose();
37 }
38
39 /// <summary>
40 /// 由终结器调用以释放资源。
41 /// </summary>
42 ~DisposableObject()
43 {
44 Dispose(false);
45 }
46
47 public void DoSomething()
48 {
49 if (_disposed) throw new ObjectDisposedException("无法访问已经释放的资源。");
50 // TODO somethings
51 }
52
53 /// <summary>
54 /// 执行与释放或重置非托管资源相关的应用程序定义的任务。
55 /// 派生类中重写此方法时,需要释放派生类中额外使用的资源。
56 /// </summary>
57 protected virtual void Dispose(bool disposing)
58 {
59 if (_disposed)
60 {
61 return;
62 }
63
64 if (disposing)
65 {
66 // TODO 清理托管资源
67 }
68
69 // TODO 1.清理非托管资源 2.将大对象{一个对象如果超过85000byte(经验值),那么将会被分配到大对象堆上(LOH:large object heap)}设置为null
70
71 _disposed = true; // 标记已经被释放。
72 }
73 }