diff --git a/Implab/Components/App.cs b/Implab/Components/App.cs --- a/Implab/Components/App.cs +++ b/Implab/Components/App.cs @@ -8,12 +8,17 @@ namespace Implab.Components { public static class App { readonly static ComponentContainer _root = new ComponentContainer(); + /// + /// The container for application level components. + /// + /// Pools of disposable objects can be placed here and they will be automatically + /// disposed when application domain is unloaded. public static ICollection RootContainer { get { return _root; } } static App() { - AppDomain.CurrentDomain.ProcessExit += (sender, e) => _root.Dispose(); + AppDomain.CurrentDomain.DomainUnload += (sender, e) => _root.Dispose(); } } } diff --git a/Implab/Components/ComponentContainer.cs b/Implab/Components/ComponentContainer.cs --- a/Implab/Components/ComponentContainer.cs +++ b/Implab/Components/ComponentContainer.cs @@ -4,12 +4,18 @@ using System.Linq; namespace Implab.Components { /// - /// Component container. + /// 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; @@ -23,21 +29,37 @@ namespace Implab.Components { 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) @@ -45,12 +67,22 @@ namespace Implab.Components { } } + /// + /// 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) { @@ -64,6 +96,13 @@ namespace Implab.Components { 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"); @@ -75,6 +114,10 @@ namespace Implab.Components { } } + /// + /// 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(); diff --git a/Implab/Components/DisposablePool.cs b/Implab/Components/DisposablePool.cs --- a/Implab/Components/DisposablePool.cs +++ b/Implab/Components/DisposablePool.cs @@ -4,7 +4,16 @@ using System.Threading; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -namespace Implab { +namespace Implab.Components { + /// + /// The base class for implementing pools of disposable objects. + /// + /// + /// This class maintains a set of pre-created objects and which are frequently allocated and released + /// by clients. The pool maintains maximum number of unsued object, any object above this limit is disposed, + /// if the pool is empty it will create new objects on demand. + /// Instances of this class are thread-safe. + /// public abstract class DisposablePool : IDisposable { readonly int m_size; readonly AsyncQueue m_queue = new AsyncQueue(); @@ -62,8 +71,9 @@ namespace Implab { ((IDisposable)instance).Dispose() ; } else { - if (instance is IDisposable) - ((IDisposable)instance).Dispose(); + var disposable = instance as IDisposable; + if (disposable != null) + disposable.Dispose(); } } @@ -71,9 +81,11 @@ namespace Implab { if (disposing) { m_disposed = true; T instance; - while (m_queue.TryDequeue(out instance)) - if (instance is IDisposable) - ((IDisposable)instance).Dispose(); + while (m_queue.TryDequeue(out instance)) { + var disposable = instance as IDisposable; + if (disposable != null) + disposable.Dispose(); + } } }