comparison Implab/Components/ComponentContainer.cs @ 216:1e082fb67a46 v2

Fixed component container
author cin
date Tue, 25 Apr 2017 19:51:33 +0300
parents b933ec88446e
children
comparison
equal deleted inserted replaced
215:fe5101083150 216:1e082fb67a46
6 /// <summary> 6 /// <summary>
7 /// Component container, used to store track components in multi-threaded environmment. 7 /// Component container, used to store track components in multi-threaded environmment.
8 /// </summary> 8 /// </summary>
9 /// <remarks>Instanses of this class are thread safe.</remarks> 9 /// <remarks>Instanses of this class are thread safe.</remarks>
10 public class ComponentContainer<T> : Disposable, ICollection<T> { 10 public class ComponentContainer<T> : Disposable, ICollection<T> {
11 readonly HashSet<T> m_components = new HashSet<T>(); 11 List<T> m_components = new List<T>();
12 readonly object m_lock = new object();
12 13
13 /// <summary> 14 /// <summary>
14 /// Removes currently stored compoenents from the container and disposes them if possible. 15 /// Removes currently stored compoenents from the container and disposes them if possible.
15 /// </summary> 16 /// </summary>
16 /// <remarks> 17 /// <remarks>
17 /// A new components may be added before this method completes. 18 /// A new components may be added before this method completes.
18 /// </remarks> 19 /// </remarks>
19 public void Clear() { 20 public void Clear() {
20 T[] removed; 21 List<T> removed;
21 22
22 lock (m_components) { 23 lock (m_lock) {
23 removed = new T[m_components.Count]; 24 removed = m_components;
24 m_components.CopyTo(removed); 25 m_components = new List<T>();
25 m_components.Clear();
26 } 26 }
27 27
28 foreach (var item in removed.OfType<IDisposable>()) 28 foreach (var item in removed.OfType<IDisposable>())
29 item.Dispose(); 29 item.Dispose();
30 } 30 }
32 /// <summary> 32 /// <summary>
33 /// Checks whether the specified item in the collection. 33 /// Checks whether the specified item in the collection.
34 /// </summary> 34 /// </summary>
35 /// <param name="item">The item to check.</param> 35 /// <param name="item">The item to check.</param>
36 public bool Contains(T item) { 36 public bool Contains(T item) {
37 lock (m_components) 37 lock (m_lock)
38 return m_components.Contains(item); 38 return m_components.Contains(item);
39 } 39 }
40 40
41 /// <summary> 41 /// <summary>
42 /// Copies currently stored components to the specified array. 42 /// Copies currently stored components to the specified array.
43 /// </summary> 43 /// </summary>
44 /// <param name="array">A destination array for components.</param> 44 /// <param name="array">A destination array for components.</param>
45 /// <param name="arrayIndex">A starting index in the destination array.</param> 45 /// <param name="arrayIndex">A starting index in the destination array.</param>
46 public void CopyTo(T[] array, int arrayIndex) { 46 public void CopyTo(T[] array, int arrayIndex) {
47 lock (m_components) 47 lock (m_lock)
48 m_components.CopyTo(array, arrayIndex); 48 m_components.CopyTo(array, arrayIndex);
49 } 49 }
50 50
51 /// <summary> 51 /// <summary>
52 /// Remove the specified item from the collection. 52 /// Remove the specified item from the collection.
53 /// </summary> 53 /// </summary>
54 /// <param name="item">The item to remove.</param> 54 /// <param name="item">The item to remove.</param>
55 public bool Remove(T item) { 55 public bool Remove(T item) {
56 lock (m_components) 56 lock (m_lock)
57 return m_components.Remove(item); 57 return m_components.Remove(item);
58 } 58 }
59 59
60 /// <summary> 60 /// <summary>
61 /// Gets the count of components in the collection. 61 /// Gets the count of components in the collection.
62 /// </summary> 62 /// </summary>
63 public int Count { 63 public int Count {
64 get { 64 get {
65 lock (m_components) 65 lock (m_lock)
66 return m_components.Count; 66 return m_components.Count;
67 } 67 }
68 } 68 }
69 69
70 /// <summary> 70 /// <summary>
82 /// <summary> 82 /// <summary>
83 /// Gets the enumerator for components in the collection. 83 /// Gets the enumerator for components in the collection.
84 /// </summary> 84 /// </summary>
85 /// <returns>The enumerator.</returns> 85 /// <returns>The enumerator.</returns>
86 public IEnumerator<T> GetEnumerator() { 86 public IEnumerator<T> GetEnumerator() {
87 T[] items; 87 T[] items = new T[m_components.Count];
88 lock (m_components) { 88 lock (m_lock) {
89 items = new T[m_components.Count];
90 m_components.CopyTo(items); 89 m_components.CopyTo(items);
91 return (IEnumerator<T>)items.GetEnumerator();
92 } 90 }
91 return (IEnumerator<T>)items.GetEnumerator();
93 } 92 }
94 93
95 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { 94 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
96 return GetEnumerator(); 95 return GetEnumerator();
97 } 96 }
103 /// <remarks> 102 /// <remarks>
104 /// If the collection is alredy disposed, the item isn't added to the collection and disposed if possible. 103 /// If the collection is alredy disposed, the item isn't added to the collection and disposed if possible.
105 /// </remarks> 104 /// </remarks>
106 public void Add(T item) { 105 public void Add(T item) {
107 Safe.ArgumentNotNull(item, "item"); 106 Safe.ArgumentNotNull(item, "item");
108 107 bool dispose = false;
109 lock (m_components) { 108 lock (m_lock) {
110 if (IsDisposed) 109 if (IsDisposed)
111 Safe.Dispose(item); 110 dispose = true;
112 else 111 else
113 m_components.Add(item); 112 m_components.Add(item);
114 } 113 }
114 if (dispose)
115 Safe.Dispose(item);
115 } 116 }
116 117
117 /// <summary> 118 /// <summary>
118 /// Disposes the components stored in the collection. 119 /// Disposes the components stored in the collection.
119 /// </summary> 120 /// </summary>
120 /// <param name="disposing">If set to <c>true</c> the collection is disposing.</param> 121 /// <param name="disposing">If set to <c>true</c> the collection is disposing.</param>
121 protected override void Dispose(bool disposing) { 122 protected override void Dispose(bool disposing) {
123 if (disposing)
124 Clear();
125
122 base.Dispose(disposing); 126 base.Dispose(disposing);
123 Clear();
124 } 127 }
125 } 128 }
126 } 129 }
127 130