Mercurial > pub > ImplabNet
view Implab/Components/ComponentContainer.cs @ 187:dd4a3590f9c6 ref20160224
Reworked cancelation handling, if the cancel handler isn't specified the OperationCanceledException will be handled by the error handler
Any unhandled OperationCanceledException will cause the promise cancelation
author | cin |
---|---|
date | Tue, 19 Apr 2016 17:35:20 +0300 |
parents | b933ec88446e |
children | 1e082fb67a46 |
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> { readonly HashSet<T> m_components = new HashSet<T>(); /// <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() { T[] removed; lock (m_components) { removed = new T[m_components.Count]; m_components.CopyTo(removed); m_components.Clear(); } 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_components) 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_components) 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_components) return m_components.Remove(item); } /// <summary> /// Gets the count of components in the collection. /// </summary> public int Count { get { lock (m_components) 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; lock (m_components) { items = new T[m_components.Count]; 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"); lock (m_components) { if (IsDisposed) Safe.Dispose(item); else m_components.Add(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) { base.Dispose(disposing); Clear(); } } }