Mercurial > pub > ImplabNet
annotate Implab/ObjectPool.cs @ 133:6c49d02a9a05 v2
sync
author | cin |
---|---|
date | Mon, 09 Feb 2015 00:28:13 +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 } |