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