annotate Implab/Components/Disposable.cs @ 196:40d7fed4a09e

fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
author cin
date Mon, 29 Aug 2016 23:15:51 +0300
parents 240aa6994018
children 7d07503621fe
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
1 using Implab.Diagnostics;
240aa6994018 component model refactoring
cin
parents:
diff changeset
2 using System;
240aa6994018 component model refactoring
cin
parents:
diff changeset
3 using System.Threading;
240aa6994018 component model refactoring
cin
parents:
diff changeset
4
240aa6994018 component model refactoring
cin
parents:
diff changeset
5 namespace Implab.Components {
240aa6994018 component model refactoring
cin
parents:
diff changeset
6 /// <summary>
240aa6994018 component model refactoring
cin
parents:
diff changeset
7 /// Base class the objects which support disposing.
240aa6994018 component model refactoring
cin
parents:
diff changeset
8 /// </summary>
240aa6994018 component model refactoring
cin
parents:
diff changeset
9 public class Disposable : IDisposable {
240aa6994018 component model refactoring
cin
parents:
diff changeset
10
240aa6994018 component model refactoring
cin
parents:
diff changeset
11 int m_disposed;
240aa6994018 component model refactoring
cin
parents:
diff changeset
12
240aa6994018 component model refactoring
cin
parents:
diff changeset
13 public event EventHandler Disposed;
240aa6994018 component model refactoring
cin
parents:
diff changeset
14
240aa6994018 component model refactoring
cin
parents:
diff changeset
15 public bool IsDisposed {
240aa6994018 component model refactoring
cin
parents:
diff changeset
16 get {
240aa6994018 component model refactoring
cin
parents:
diff changeset
17 Thread.MemoryBarrier();
240aa6994018 component model refactoring
cin
parents:
diff changeset
18 return m_disposed != 0;
240aa6994018 component model refactoring
cin
parents:
diff changeset
19 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
20 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
21
240aa6994018 component model refactoring
cin
parents:
diff changeset
22 /// <summary>
240aa6994018 component model refactoring
cin
parents:
diff changeset
23 /// Asserts the object is not disposed.
240aa6994018 component model refactoring
cin
parents:
diff changeset
24 /// </summary>
240aa6994018 component model refactoring
cin
parents:
diff changeset
25 /// <exception cref="ObjectDisposedException">The object is disposed</exception>
240aa6994018 component model refactoring
cin
parents:
diff changeset
26 /// <remarks>
240aa6994018 component model refactoring
cin
parents:
diff changeset
27 /// Успешная проверка того, что объект не освобожден еще не гарантирует, что он не
240aa6994018 component model refactoring
cin
parents:
diff changeset
28 /// будет освобожден сразу после нее, поэтому методы использующие проверку должны
240aa6994018 component model refactoring
cin
parents:
diff changeset
29 /// учитывать, что объект может быть освобожден из параллельного потока.
240aa6994018 component model refactoring
cin
parents:
diff changeset
30 /// Данны метод служит для упрощения отладки ошибок при использовании объекта после его
240aa6994018 component model refactoring
cin
parents:
diff changeset
31 /// освобождения.
240aa6994018 component model refactoring
cin
parents:
diff changeset
32 /// </remarks>
240aa6994018 component model refactoring
cin
parents:
diff changeset
33 /// <example>
240aa6994018 component model refactoring
cin
parents:
diff changeset
34 /// // пример синхронизированного освобождения ресурсов
240aa6994018 component model refactoring
cin
parents:
diff changeset
35 /// class FileStore : Disposable {
240aa6994018 component model refactoring
cin
parents:
diff changeset
36 /// readonly TextWriter m_file;
240aa6994018 component model refactoring
cin
parents:
diff changeset
37 /// readonly obejct m_sync = new object();
240aa6994018 component model refactoring
cin
parents:
diff changeset
38 ///
240aa6994018 component model refactoring
cin
parents:
diff changeset
39 /// public FileStore(string file) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
40 /// m_file = new TextWriter(File.OpenWrite(file));
240aa6994018 component model refactoring
cin
parents:
diff changeset
41 /// }
240aa6994018 component model refactoring
cin
parents:
diff changeset
42 ///
240aa6994018 component model refactoring
cin
parents:
diff changeset
43 /// public void Write(string text) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
44 /// lock(m_sync) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
45 /// AssertNotDisposed();
240aa6994018 component model refactoring
cin
parents:
diff changeset
46 /// m_file.Write(text);
240aa6994018 component model refactoring
cin
parents:
diff changeset
47 /// }
240aa6994018 component model refactoring
cin
parents:
diff changeset
48 /// }
240aa6994018 component model refactoring
cin
parents:
diff changeset
49 ///
240aa6994018 component model refactoring
cin
parents:
diff changeset
50 /// protected override void Dispose(bool disposing) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
51 /// if (disposing)
240aa6994018 component model refactoring
cin
parents:
diff changeset
52 /// lock(m_sync) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
53 /// m_file.Dipose();
240aa6994018 component model refactoring
cin
parents:
diff changeset
54 /// base.Dispose(true);
240aa6994018 component model refactoring
cin
parents:
diff changeset
55 /// }
240aa6994018 component model refactoring
cin
parents:
diff changeset
56 /// else
240aa6994018 component model refactoring
cin
parents:
diff changeset
57 /// base.Dispose(false);
240aa6994018 component model refactoring
cin
parents:
diff changeset
58 /// }
240aa6994018 component model refactoring
cin
parents:
diff changeset
59 /// }
240aa6994018 component model refactoring
cin
parents:
diff changeset
60 /// <example>
240aa6994018 component model refactoring
cin
parents:
diff changeset
61 protected void AssertNotDisposed() {
240aa6994018 component model refactoring
cin
parents:
diff changeset
62 Thread.MemoryBarrier();
240aa6994018 component model refactoring
cin
parents:
diff changeset
63 if (m_disposed != 0)
240aa6994018 component model refactoring
cin
parents:
diff changeset
64 throw new ObjectDisposedException(ToString());
240aa6994018 component model refactoring
cin
parents:
diff changeset
65 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
66 /// <summary>
240aa6994018 component model refactoring
cin
parents:
diff changeset
67 /// Вызывает событие <see cref="Disposed"/>
240aa6994018 component model refactoring
cin
parents:
diff changeset
68 /// </summary>
240aa6994018 component model refactoring
cin
parents:
diff changeset
69 /// <param name="disposing">Признак того, что нужно освободить ресурсы, иначе данный метод
240aa6994018 component model refactoring
cin
parents:
diff changeset
70 /// вызван сборщиком мусора и нужно освобождать ТОЛЬКО неуправляемые ресурсы ТОЛЬКО этого
240aa6994018 component model refactoring
cin
parents:
diff changeset
71 /// объекта.</param>
240aa6994018 component model refactoring
cin
parents:
diff changeset
72 /// <remarks>
240aa6994018 component model refactoring
cin
parents:
diff changeset
73 /// Данный метод вызывается гарантированно один раз даже при одновременном вызове <see cref="Dispose()"/>
240aa6994018 component model refactoring
cin
parents:
diff changeset
74 /// из нескольких потоков.
240aa6994018 component model refactoring
cin
parents:
diff changeset
75 /// </remarks>
240aa6994018 component model refactoring
cin
parents:
diff changeset
76 protected virtual void Dispose(bool disposing) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
77 if (disposing) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
78 EventHandler temp = Disposed;
240aa6994018 component model refactoring
cin
parents:
diff changeset
79 if (temp != null)
240aa6994018 component model refactoring
cin
parents:
diff changeset
80 temp(this, EventArgs.Empty);
240aa6994018 component model refactoring
cin
parents:
diff changeset
81 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
82 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
83
240aa6994018 component model refactoring
cin
parents:
diff changeset
84 public void Dispose() {
240aa6994018 component model refactoring
cin
parents:
diff changeset
85 if (Interlocked.Increment(ref m_disposed) == 1) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
86 Dispose(true);
240aa6994018 component model refactoring
cin
parents:
diff changeset
87 GC.SuppressFinalize(this);
240aa6994018 component model refactoring
cin
parents:
diff changeset
88 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
89 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
90
240aa6994018 component model refactoring
cin
parents:
diff changeset
91 /// <summary>
240aa6994018 component model refactoring
cin
parents:
diff changeset
92 /// Записывает сообщение об утечке объекта.
240aa6994018 component model refactoring
cin
parents:
diff changeset
93 /// </summary>
240aa6994018 component model refactoring
cin
parents:
diff changeset
94 protected virtual void ReportObjectLeaks() {
240aa6994018 component model refactoring
cin
parents:
diff changeset
95 TraceLog.TraceWarning("The object is marked as disposable but isn't disposed properly: {0}", this);
240aa6994018 component model refactoring
cin
parents:
diff changeset
96 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
97
240aa6994018 component model refactoring
cin
parents:
diff changeset
98 ~Disposable() {
240aa6994018 component model refactoring
cin
parents:
diff changeset
99 Dispose(false);
240aa6994018 component model refactoring
cin
parents:
diff changeset
100 ReportObjectLeaks();
240aa6994018 component model refactoring
cin
parents:
diff changeset
101 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
102 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
103 }