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