Mercurial > pub > ImplabNet
view Implab/Components/ComponentContainer.cs @ 240:fa6cbf4d8841 v3
refactoring, moving to dotnercore, simplifying promises
author | cin |
---|---|
date | Tue, 23 Jan 2018 19:39:21 +0300 |
parents | 1e082fb67a46 |
children |
line wrap: on
line source
using System; using System.Collections.Generic; using System.Linq; namespace Implab.Components { /// <summary> /// Component container, used to store track components in multi-threaded environmment. /// </summary> /// <remarks>Instanses of this class are thread safe.</remarks> public class ComponentContainer<T> : Disposable, ICollection<T> { List<T> m_components = new List<T>(); readonly object m_lock = new object(); /// <summary> /// Removes currently stored compoenents from the container and disposes them if possible. /// </summary> /// <remarks> /// A new components may be added before this method completes. /// </remarks> public void Clear() { List<T> removed; lock (m_lock) { removed = m_components; m_components = new List<T>(); } foreach (var item in removed.OfType<IDisposable>()) item.Dispose(); } /// <summary> /// Checks whether the specified item in the collection. /// </summary> /// <param name="item">The item to check.</param> public bool Contains(T item) { lock (m_lock) return m_components.Contains(item); } /// <summary> /// Copies currently stored components to the specified array. /// </summary> /// <param name="array">A destination array for components.</param> /// <param name="arrayIndex">A starting index in the destination array.</param> public void CopyTo(T[] array, int arrayIndex) { lock (m_lock) m_components.CopyTo(array, arrayIndex); } /// <summary> /// Remove the specified item from the collection. /// </summary> /// <param name="item">The item to remove.</param> public bool Remove(T item) { lock (m_lock) return m_components.Remove(item); } /// <summary> /// Gets the count of components in the collection. /// </summary> public int Count { get { lock (m_lock) return m_components.Count; } } /// <summary> /// Gets a value indicating whether this instance is read only. /// </summary> /// <remarks> /// Always false. /// </remarks> public bool IsReadOnly { get { return false; } } /// <summary> /// Gets the enumerator for components in the collection. /// </summary> /// <returns>The enumerator.</returns> public IEnumerator<T> GetEnumerator() { T[] items = new T[m_components.Count]; lock (m_lock) { m_components.CopyTo(items); } return (IEnumerator<T>)items.GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); } /// <summary> /// Add the specified item to the collection. /// </summary> /// <param name="item">The item to add.</param> /// <remarks> /// If the collection is alredy disposed, the item isn't added to the collection and disposed if possible. /// </remarks> public void Add(T item) { Safe.ArgumentNotNull(item, "item"); bool dispose = false; lock (m_lock) { if (IsDisposed) dispose = true; else m_components.Add(item); } if (dispose) Safe.Dispose(item); } /// <summary> /// Disposes the components stored in the collection. /// </summary> /// <param name="disposing">If set to <c>true</c> the collection is disposing.</param> protected override void Dispose(bool disposing) { if (disposing) Clear(); base.Dispose(disposing); } } }