##// END OF EJS Templates
minor changes
minor changes

File last commit:

r119:2573b562e328 v2
r146:e03ccec4a08d v2
Show More
ObjectPool.cs
60 lines | 2.4 KiB | text/x-csharp | CSharpLexer
using Implab.Parallels;
using System;
using System.Threading;
namespace Implab {
/// <summary>
/// Базовый класс для создания пулов объектов.
/// </summary>
/// <remarks>
/// <para>Пул объектов позволяет многократно использовать один и тотже объект,
/// что актуально для объектов, создание которых требует существенных ресурсов.
/// Пул объектов использует слабые ссылки, чтобы не препятствовать освобождению
/// ресурсов и создает новые объекты при необходимости.</para>
/// <para>
/// Наследники должны реализовывать метод <see cref="CreateInstance()"/> для создания
/// новых экземпляров.
/// </para>
/// <para>Пул поддерживает обращения сразу из нескольких потоков.</para>
/// </remarks>
public abstract class ObjectPool<T> where T : class {
readonly AsyncQueue<WeakReference> m_queue = new AsyncQueue<WeakReference>();
readonly int m_size;
int m_count = 0;
protected ObjectPool() : this(Environment.ProcessorCount+1) {
}
protected ObjectPool(int size) {
Safe.ArgumentInRange(size,1,size,"size");
m_size = size;
}
protected abstract T CreateInstance();
protected virtual void CleanupInstance(T instance) {
}
public T Allocate() {
WeakReference reference;
while (m_queue.TryDequeue(out reference)) {
Interlocked.Decrement(ref m_count);
object instance = reference.Target;
if (instance == null)
continue;
return (T)instance;
}
return CreateInstance();
}
public void Release(T instance) {
if (m_count < m_size && instance != null) {
Interlocked.Increment(ref m_count);
CleanupInstance(instance);
m_queue.Enqueue(new WeakReference(instance));
}
}
}
}