Mercurial > pub > ImplabNet
view Implab/SyncPool.cs @ 81:2c5631b43c7d v2
dispatch pool rewritten
author | cin |
---|---|
date | Fri, 26 Sep 2014 20:44:01 +0400 |
parents | 4f20870d0816 |
children |
line wrap: on
line source
using System; using Implab.Parallels; using System.Threading; namespace Implab { /*public class SyncPool<T> : IDisposable { readonly Func<T> m_factory; readonly Action<T> m_cleanup; readonly int m_size; readonly MTQueue<T> m_queue = new MTQueue<T>(); volatile bool m_disposed; volatile int m_count; public SyncPool(Func<T> factory, Action<T> cleanup, int size) { Safe.ArgumentNotNull(factory, "factory"); Safe.ArgumentInRange(size, 1, size, "size"); m_factory = factory; m_cleanup = cleanup; m_size = size; } public SyncPool(Func<T> factory, Action<T> cleanup) : this(factory,cleanup,Environment.ProcessorCount+1) { } public SyncPool(Func<T> factory) : this(factory,null,Environment.ProcessorCount+1) { } public SyncPoolWrapper<T> Allocate() { if (m_disposed) throw new ObjectDisposedException(this.ToString()); T instance; if (m_queue.TryDequeue(out instance)) { Interlocked.Decrement(ref m_count); return instance; } else { instance = m_factory(); } return new SyncPoolWrapper<T>(instance, this); } public void Release(T instance) { if (m_count < m_size && !m_disposed) { Interlocked.Increment(ref m_count); if (m_cleanup != null) m_cleanup(instance); m_queue.Enqueue(instance); // пока элемент возвращался в кеш, была начата операция освобождения всего кеша // и возможно уже законцена, в таком случае следует извлечь элемент обратно и // освободить его. Если операция освобождения кеша еще не заврешилась, то будет // изъят и освобожден произвольный элемен, что не повлияет на ход всего процесса. if (m_disposed && m_queue.TryDequeue(out instance)) Safe.Dispose(instance); } else { Safe.Dispose(instance); } } protected virtual void Dispose(bool disposing) { if (disposing) { m_disposed = true; T instance; while (m_queue.TryDequeue(out instance)) Safe.Dispose(instance); } } #region IDisposable implementation public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } #endregion }*/ }