using System.Collections.Concurrent;
using DotNext;
namespace Common;
///
/// [TODO:description]
///
public class SemaphorePool
{
private SemaphoreSlim semaphore;
private ConcurrentQueue queue;
private int beginNum;
///
/// [TODO:description]
///
public int RemainingCount { get; }
///
/// [TODO:description]
///
public int MaxCount { get; }
///
/// [TODO:description]
///
/// [TODO:parameter]
/// [TODO:parameter]
/// [TODO:return]
public SemaphorePool(int initialCount, int beginNum = 0)
{
semaphore = new SemaphoreSlim(initialCount);
queue = new ConcurrentQueue();
this.beginNum = beginNum;
this.RemainingCount = initialCount;
this.MaxCount = initialCount;
for (int i = 0; i < initialCount; i++)
{
queue.Enqueue(beginNum + i);
}
}
///
/// [TODO:description]
///
/// [TODO:parameter]
/// [TODO:parameter]
/// [TODO:parameter]
/// [TODO:return]
public SemaphorePool(int initialCount, int maxCount, int beginNum = 0)
{
semaphore = new SemaphoreSlim(initialCount, maxCount);
queue = new ConcurrentQueue();
this.beginNum = beginNum;
this.RemainingCount = initialCount;
this.MaxCount = maxCount;
for (int i = 0; i < initialCount; i++)
{
queue.Enqueue(beginNum + i);
}
}
///
/// [TODO:description]
///
/// [TODO:return]
public Result Wait()
{
semaphore.Wait();
int pop;
if (queue.TryDequeue(out pop))
{
return pop;
}
else
{
return new(new Exception($"TODO"));
}
}
///
/// [TODO:description]
///
/// [TODO:return]
public async ValueTask> WaitAsync()
{
await semaphore.WaitAsync();
int pop;
if (queue.TryDequeue(out pop))
{
return pop;
}
else
{
return new(new Exception($"TODO"));
}
}
///
/// [TODO:description]
///
/// [TODO:return]
public void Release()
{
semaphore.Release();
queue.Clear();
for (int i = 0; i < MaxCount; i++)
{
queue.Enqueue(beginNum + i);
}
}
}