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)); |