Mercurial > pub > ImplabNet
diff Implab/Components/ObjectPool.cs @ 152:240aa6994018 v2
component model refactoring
author | cin |
---|---|
date | Thu, 11 Feb 2016 01:56:27 +0300 |
parents | |
children | 2dcdee4c0810 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/Components/ObjectPool.cs Thu Feb 11 01:56:27 2016 +0300 @@ -0,0 +1,60 @@ +using Implab.Parallels; +using System; +using System.Threading; + +namespace Implab.Components { + /// <summary> + /// Базовый класс для создания пулов объектов. + /// </summary> + /// <remarks> + /// <para>Пул объектов позволяет многократно использовать один и тотже объект, + /// что актуально для объектов, создание которых требует существенных ресурсов. + /// Пул объектов использует слабые ссылки, чтобы не препятствовать освобождению + /// ресурсов и создает новые объекты при необходимости.</para> + /// <para> + /// Наследники должны реализовывать метод <see cref="CreateInstance()"/> для создания + /// новых экземпляров. + /// </para> + /// <para>Пул поддерживает обращения сразу из нескольких потоков.</para> + /// </remarks> + public abstract class ObjectPool<T> where T : class { + readonly AsyncQueue<WeakReference> m_queue = new AsyncQueue<WeakReference>(); + readonly int m_size; + int m_count = 0; + + protected ObjectPool() : this(Environment.ProcessorCount+1) { + + } + + protected ObjectPool(int size) { + Safe.ArgumentInRange(size,1,size,"size"); + + m_size = size; + } + + protected abstract T CreateInstance(); + + protected virtual void CleanupInstance(T instance) { + } + + public T Allocate() { + WeakReference reference; + while (m_queue.TryDequeue(out reference)) { + Interlocked.Decrement(ref m_count); + object instance = reference.Target; + if (instance == null) + continue; + return (T)instance; + } + return CreateInstance(); + } + + public void Release(T instance) { + if (m_count < m_size && instance != null) { + Interlocked.Increment(ref m_count); + CleanupInstance(instance); + m_queue.Enqueue(new WeakReference(instance)); + } + } + } +}