我有一个循环池实现
public class CircularPool<T> where T : class, new()
{
private readonly Queue<T> instances;
public CircularPool(int size)
{
instances = new Queue<T>(size);
for (var i = 0; i < size; ++i)
{
instances.Enqueue(new T());
}
}
public T GetInstance()
{
var instance = instances.Dequeue();
instances.Enqueue(instance); // Circular pool
return instance;
}
public void ReturnInstance(T instance)
{
// What does returning look like?
// Could use IsActive flag?
}
public IEnumerable<T> GetActiveInstances()
{
return instances; // TODO: Only want the active ones
}
}我希望能够跟踪池中当前正在使用的实例,这样我就可以迭代它们并执行各种操作
var pool = new CircularPool<Foo>(5);
var fooInstanceA = pool.GetInstance();
var fooInstanceB = pool.GetInstance();
var fooInstanceC = pool.GetInstance();
pool.ReturnInstance(fooInstanceB);
foreach (var activeInstance in pool.GetActiveInstances())
{
// Do stuff with active instances (fooInstanceA then fooInstanceC)
}如何正确获取按年限排序的活动实例?
假设这是一个循环池,那么如果在没有调用ReturnInstance的情况下调用GetInstance的次数超过池的大小,那么将返回最老的活动实例,并成为最年轻的活动实例。这应该相应地反映在GetActiveInstances中。
另外,在循环池的上下文中,ReturnInstance应该是什么样子?
发布于 2021-03-19 17:17:50
我们可以对所有实例使用数组T[],对活动实例使用HashSet<T>:
public class CircularPool<T> where T : class, new() {
private readonly T[] m_All;
private readonly HashSet<T> m_InUse;
private int m_Index; // Index to start looking for a free instance
public CircularPool(int size) {
if (size <= 0)
throw new ArgumentOutOfRangeException(nameof(size));
m_InUse = new HashSet<T>(size);
m_All = Enumerable.Range(0, size).Select(_ => new T()).ToArray();
}
public bool TryGetInstance(out T availableInstance) {
for (int i = 0; i < m_All.Length; ++i) {
int index = (i + m_Index) % m_All.Length;
if (m_InUse.Add(m_All[index])) {
availableInstance = m_All[index];
m_Index = index + 1;
return true;
}
}
availableInstance = default(T); // no available instances found
return false;
}
public T GetInstance() => TryGetInstance(out var result)
? result
: throw new InvalidOperationException("There are no available instances.");
public bool ReturnInstance(T instance) => m_InUse.Remove(instance);
public IEnumerable<T> GetActiveInstances() => m_InUse;
public IEnumerable<T> GetAvailableInstances() =>
m_All.Where(item => !m_All.Contains(item));
}https://stackoverflow.com/questions/66705134
复制相似问题