using System; using System.Collections.Generic; using System.Linq; namespace Implab.Components { /// /// Component container, used to store track components in multi-threaded environmment. /// /// Instanses of this class are thread safe. public class ComponentContainer : Disposable, ICollection { readonly HashSet m_components = new HashSet(); /// /// Removes currently stored compoenents from the container and disposes them if possible. /// /// /// A new components may be added before this method completes. /// 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()) item.Dispose(); } /// /// Checks whether the specified item in the collection. /// /// The item to check. public bool Contains(T item) { lock (m_components) return m_components.Contains(item); } /// /// Copies currently stored components to the specified array. /// /// A destination array for components. /// A starting index in the destination array. public void CopyTo(T[] array, int arrayIndex) { lock (m_components) m_components.CopyTo(array, arrayIndex); } /// /// Remove the specified item from the collection. /// /// The item to remove. public bool Remove(T item) { lock (m_components) return m_components.Remove(item); } /// /// Gets the count of components in the collection. /// public int Count { get { lock (m_components) return m_components.Count; } } /// /// Gets a value indicating whether this instance is read only. /// /// /// Always false. /// public bool IsReadOnly { get { return false; } } /// /// Gets the enumerator for components in the collection. /// /// The enumerator. public IEnumerator GetEnumerator() { T[] items; lock (m_components) { items = new T[m_components.Count]; m_components.CopyTo(items); return (IEnumerator)items.GetEnumerator(); } } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); } /// /// Add the specified item to the collection. /// /// The item to add. /// /// If the collection is alredy disposed, the item isn't added to the collection and disposed if possible. /// public void Add(T item) { Safe.ArgumentNotNull(item, "item"); lock (m_components) { if (IsDisposed) Safe.Dispose(item); else m_components.Add(item); } } /// /// Disposes the components stored in the collection. /// /// If set to true the collection is disposing. protected override void Dispose(bool disposing) { base.Dispose(disposing); Clear(); } } }