Mercurial > pub > ImplabNet
annotate Implab/ObjectPool.cs @ 145:706fccb85524 v2
RC: cancellation support for promises + tests
| author | cin |
|---|---|
| date | Sun, 08 Mar 2015 02:52:27 +0300 |
| parents | 2573b562e328 |
| children |
| rev | line source |
|---|---|
| 117 | 1 using Implab.Parallels; |
| 2 using System; | |
| 3 using System.Threading; | |
| 4 | |
| 5 namespace Implab { | |
| 6 /// <summary> | |
| 7 /// Базовый класс для создания пулов объектов. | |
| 8 /// </summary> | |
| 9 /// <remarks> | |
| 10 /// <para>Пул объектов позволяет многократно использовать один и тотже объект, | |
| 11 /// что актуально для объектов, создание которых требует существенных ресурсов. | |
| 12 /// Пул объектов использует слабые ссылки, чтобы не препятствовать освобождению | |
| 13 /// ресурсов и создает новые объекты при необходимости.</para> | |
| 14 /// <para> | |
| 15 /// Наследники должны реализовывать метод <see cref="CreateInstance()"/> для создания | |
| 16 /// новых экземпляров. | |
| 17 /// </para> | |
| 18 /// <para>Пул поддерживает обращения сразу из нескольких потоков.</para> | |
| 19 /// </remarks> | |
| 20 public abstract class ObjectPool<T> where T : class { | |
|
119
2573b562e328
Promises rewritten, added improved version of AsyncQueue
cin
parents:
117
diff
changeset
|
21 readonly AsyncQueue<WeakReference> m_queue = new AsyncQueue<WeakReference>(); |
| 117 | 22 readonly int m_size; |
| 23 int m_count = 0; | |
| 24 | |
| 25 protected ObjectPool() : this(Environment.ProcessorCount+1) { | |
| 26 | |
| 27 } | |
| 28 | |
| 29 protected ObjectPool(int size) { | |
| 30 Safe.ArgumentInRange(size,1,size,"size"); | |
| 31 | |
| 32 m_size = size; | |
| 33 } | |
| 34 | |
| 35 protected abstract T CreateInstance(); | |
| 36 | |
| 37 protected virtual void CleanupInstance(T instance) { | |
| 38 } | |
| 39 | |
| 40 public T Allocate() { | |
| 41 WeakReference reference; | |
| 42 while (m_queue.TryDequeue(out reference)) { | |
| 43 Interlocked.Decrement(ref m_count); | |
| 44 object instance = reference.Target; | |
| 45 if (instance == null) | |
| 46 continue; | |
| 47 return (T)instance; | |
| 48 } | |
| 49 return CreateInstance(); | |
| 50 } | |
| 51 | |
| 52 public void Release(T instance) { | |
| 53 if (m_count < m_size && instance != null) { | |
| 54 Interlocked.Increment(ref m_count); | |
| 55 CleanupInstance(instance); | |
| 56 m_queue.Enqueue(new WeakReference(instance)); | |
| 57 } | |
| 58 } | |
| 59 } | |
| 60 } |
