Mercurial > pub > ImplabNet
comparison Implab/Components/ObjectPool.cs @ 154:2dcdee4c0810 v2
docs
| author | cin | 
|---|---|
| date | Fri, 12 Feb 2016 01:00:11 +0300 | 
| parents | 240aa6994018 | 
| children | 7c7e9ad6fe4a | 
   comparison
  equal
  deleted
  inserted
  replaced
| 153:b933ec88446e | 154:2dcdee4c0810 | 
|---|---|
| 2 using System; | 2 using System; | 
| 3 using System.Threading; | 3 using System.Threading; | 
| 4 | 4 | 
| 5 namespace Implab.Components { | 5 namespace Implab.Components { | 
| 6 /// <summary> | 6 /// <summary> | 
| 7 /// Базовый класс для создания пулов объектов. | 7 /// The base class for creating object pools. | 
| 8 /// </summary> | 8 /// </summary> | 
| 9 /// <remarks> | 9 /// <remarks> | 
| 10 /// <para>Пул объектов позволяет многократно использовать один и тотже объект, | 10 /// <para>The objects pool is offers frequently requested objects to be reused, this gives | 
| 11 /// что актуально для объектов, создание которых требует существенных ресурсов. | 11 /// a gool speed improvement for the 'heavy' objects. To avoid memory overhead the pool uses | 
| 12 /// Пул объектов использует слабые ссылки, чтобы не препятствовать освобождению | 12 /// weak references allowing CG to do it's work. If there are no free objects in the pool | 
| 13 /// ресурсов и создает новые объекты при необходимости.</para> | 13 /// they are created on demand. </para> | 
| 14 /// <para> | 14 /// <para> | 
| 15 /// Наследники должны реализовывать метод <see cref="CreateInstance()"/> для создания | 15 /// Implementors need to defined a <see cref="CreateInstance()"/> method | 
| 16 /// новых экземпляров. | |
| 17 /// </para> | 16 /// </para> | 
| 18 /// <para>Пул поддерживает обращения сразу из нескольких потоков.</para> | 17 /// <para>The instances of this class are thred-safe.</para> | 
| 19 /// </remarks> | 18 /// </remarks> | 
| 20 public abstract class ObjectPool<T> where T : class { | 19 public abstract class ObjectPool<T> where T : class { | 
| 21 readonly AsyncQueue<WeakReference> m_queue = new AsyncQueue<WeakReference>(); | 20 readonly AsyncQueue<WeakReference> m_queue = new AsyncQueue<WeakReference>(); | 
| 22 readonly int m_size; | 21 readonly int m_size; | 
| 23 int m_count = 0; | 22 int m_count = 0; | 
| 30 Safe.ArgumentInRange(size,1,size,"size"); | 29 Safe.ArgumentInRange(size,1,size,"size"); | 
| 31 | 30 | 
| 32 m_size = size; | 31 m_size = size; | 
| 33 } | 32 } | 
| 34 | 33 | 
| 34 /// <summary> | |
| 35 /// Creates the instance if there are no free ones in the pool. | |
| 36 /// </summary> | |
| 37 /// <returns>The new instance.</returns> | |
| 35 protected abstract T CreateInstance(); | 38 protected abstract T CreateInstance(); | 
| 36 | 39 | 
| 40 /// <summary> | |
| 41 /// Cleanups the instance. | |
| 42 /// </summary> | |
| 43 /// <param name="instance">The instance to cleanup and prepare it for the next use.</param> | |
| 37 protected virtual void CleanupInstance(T instance) { | 44 protected virtual void CleanupInstance(T instance) { | 
| 38 } | 45 } | 
| 39 | 46 | 
| 47 /// <summary> | |
| 48 /// Allocate free instance from the pool or reates a new one. | |
| 49 /// </summary> | |
| 40 public T Allocate() { | 50 public T Allocate() { | 
| 41 WeakReference reference; | 51 WeakReference reference; | 
| 42 while (m_queue.TryDequeue(out reference)) { | 52 while (m_queue.TryDequeue(out reference)) { | 
| 43 Interlocked.Decrement(ref m_count); | 53 Interlocked.Decrement(ref m_count); | 
| 44 object instance = reference.Target; | 54 object instance = reference.Target; | 
| 47 return (T)instance; | 57 return (T)instance; | 
| 48 } | 58 } | 
| 49 return CreateInstance(); | 59 return CreateInstance(); | 
| 50 } | 60 } | 
| 51 | 61 | 
| 62 /// <summary> | |
| 63 /// Release the specified instance and returns it to the pool of free instances. | |
| 64 /// </summary> | |
| 65 /// <param name="instance">The instance to return to the pool.</param> | |
| 66 /// <remarks>Before the instance is returned to the pool the <see cref="CleanupInstance(T)"/> is called.</remarks> | |
| 52 public void Release(T instance) { | 67 public void Release(T instance) { | 
| 53 if (m_count < m_size && instance != null) { | 68 if (m_count < m_size && instance != null) { | 
| 54 Interlocked.Increment(ref m_count); | 69 Interlocked.Increment(ref m_count); | 
| 55 CleanupInstance(instance); | 70 CleanupInstance(instance); | 
| 56 m_queue.Enqueue(new WeakReference(instance)); | 71 m_queue.Enqueue(new WeakReference(instance)); | 
