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); } } }