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

component model refactoring
author cin
date Thu, 11 Feb 2016 01:56:27 +0300
parents
children 2dcdee4c0810
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
1 using Implab.Parallels;
240aa6994018 component model refactoring
cin
parents:
diff changeset
2 using System;
240aa6994018 component model refactoring
cin
parents:
diff changeset
3 using System.Threading;
240aa6994018 component model refactoring
cin
parents:
diff changeset
4
240aa6994018 component model refactoring
cin
parents:
diff changeset
5 namespace Implab.Components {
240aa6994018 component model refactoring
cin
parents:
diff changeset
6 /// <summary>
240aa6994018 component model refactoring
cin
parents:
diff changeset
7 /// Базовый класс для создания пулов объектов.
240aa6994018 component model refactoring
cin
parents:
diff changeset
8 /// </summary>
240aa6994018 component model refactoring
cin
parents:
diff changeset
9 /// <remarks>
240aa6994018 component model refactoring
cin
parents:
diff changeset
10 /// <para>Пул объектов позволяет многократно использовать один и тотже объект,
240aa6994018 component model refactoring
cin
parents:
diff changeset
11 /// что актуально для объектов, создание которых требует существенных ресурсов.
240aa6994018 component model refactoring
cin
parents:
diff changeset
12 /// Пул объектов использует слабые ссылки, чтобы не препятствовать освобождению
240aa6994018 component model refactoring
cin
parents:
diff changeset
13 /// ресурсов и создает новые объекты при необходимости.</para>
240aa6994018 component model refactoring
cin
parents:
diff changeset
14 /// <para>
240aa6994018 component model refactoring
cin
parents:
diff changeset
15 /// Наследники должны реализовывать метод <see cref="CreateInstance()"/> для создания
240aa6994018 component model refactoring
cin
parents:
diff changeset
16 /// новых экземпляров.
240aa6994018 component model refactoring
cin
parents:
diff changeset
17 /// </para>
240aa6994018 component model refactoring
cin
parents:
diff changeset
18 /// <para>Пул поддерживает обращения сразу из нескольких потоков.</para>
240aa6994018 component model refactoring
cin
parents:
diff changeset
19 /// </remarks>
240aa6994018 component model refactoring
cin
parents:
diff changeset
20 public abstract class ObjectPool<T> where T : class {
240aa6994018 component model refactoring
cin
parents:
diff changeset
21 readonly AsyncQueue<WeakReference> m_queue = new AsyncQueue<WeakReference>();
240aa6994018 component model refactoring
cin
parents:
diff changeset
22 readonly int m_size;
240aa6994018 component model refactoring
cin
parents:
diff changeset
23 int m_count = 0;
240aa6994018 component model refactoring
cin
parents:
diff changeset
24
240aa6994018 component model refactoring
cin
parents:
diff changeset
25 protected ObjectPool() : this(Environment.ProcessorCount+1) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
26
240aa6994018 component model refactoring
cin
parents:
diff changeset
27 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
28
240aa6994018 component model refactoring
cin
parents:
diff changeset
29 protected ObjectPool(int size) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
30 Safe.ArgumentInRange(size,1,size,"size");
240aa6994018 component model refactoring
cin
parents:
diff changeset
31
240aa6994018 component model refactoring
cin
parents:
diff changeset
32 m_size = size;
240aa6994018 component model refactoring
cin
parents:
diff changeset
33 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
34
240aa6994018 component model refactoring
cin
parents:
diff changeset
35 protected abstract T CreateInstance();
240aa6994018 component model refactoring
cin
parents:
diff changeset
36
240aa6994018 component model refactoring
cin
parents:
diff changeset
37 protected virtual void CleanupInstance(T instance) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
38 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
39
240aa6994018 component model refactoring
cin
parents:
diff changeset
40 public T Allocate() {
240aa6994018 component model refactoring
cin
parents:
diff changeset
41 WeakReference reference;
240aa6994018 component model refactoring
cin
parents:
diff changeset
42 while (m_queue.TryDequeue(out reference)) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
43 Interlocked.Decrement(ref m_count);
240aa6994018 component model refactoring
cin
parents:
diff changeset
44 object instance = reference.Target;
240aa6994018 component model refactoring
cin
parents:
diff changeset
45 if (instance == null)
240aa6994018 component model refactoring
cin
parents:
diff changeset
46 continue;
240aa6994018 component model refactoring
cin
parents:
diff changeset
47 return (T)instance;
240aa6994018 component model refactoring
cin
parents:
diff changeset
48 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
49 return CreateInstance();
240aa6994018 component model refactoring
cin
parents:
diff changeset
50 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
51
240aa6994018 component model refactoring
cin
parents:
diff changeset
52 public void Release(T instance) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
53 if (m_count < m_size && instance != null) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
54 Interlocked.Increment(ref m_count);
240aa6994018 component model refactoring
cin
parents:
diff changeset
55 CleanupInstance(instance);
240aa6994018 component model refactoring
cin
parents:
diff changeset
56 m_queue.Enqueue(new WeakReference(instance));
240aa6994018 component model refactoring
cin
parents:
diff changeset
57 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
58 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
59 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
60 }