comparison Implab/Components/ObjectPool.cs @ 152:240aa6994018 v2

component model refactoring
author cin
date Thu, 11 Feb 2016 01:56:27 +0300
parents
children 2dcdee4c0810
comparison
equal deleted inserted replaced
151:ec91a6dfa5b3 152:240aa6994018
1 using Implab.Parallels;
2 using System;
3 using System.Threading;
4
5 namespace Implab.Components {
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 {
21 readonly AsyncQueue<WeakReference> m_queue = new AsyncQueue<WeakReference>();
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 }