/// <summary> /// Initializes a new instance of the <see cref="Pool{T}"/> with specified upper limit. /// </summary> /// <param name="maxCapacity"></param> protected Pool(int maxCapacity) { if (maxCapacity < 1) { throw new ArgumentOutOfRangeException("maxCapacity", "Max capacity must be greater than 0"); } _storage = new ConcurrentStack <PoolSlot <T> >(); _allocSemaphore = new LockFreeSemaphore(maxCapacity, maxCapacity); }
public void MultiThread() { const int threadCount = 25; const int iterations = 25; const int resourceCount = 4; var semaphore = new LockFreeSemaphore(resourceCount); Assert.AreEqual(resourceCount, semaphore.CurrentCount); var factory = new TaskFactory(TaskScheduler.Default); ThreadPool.QueueUserWorkItem(state => { }); var tasks = new Task[threadCount]; var currentTreadCount = 0; var fails = 0; for (var t = 0; t < threadCount; t++) { tasks[t] = factory.StartNew( () => { for (var i = 0; i < iterations; i++) { if (semaphore.TryTake()) { Interlocked.Increment(ref currentTreadCount); Assert.LessOrEqual(currentTreadCount, resourceCount); Thread.Sleep(10); Interlocked.Decrement(ref currentTreadCount); semaphore.Release(); } else { Interlocked.Increment(ref fails); } } }); } Task.WaitAll(tasks); Debug.WriteLine("Fails: " + fails); Assert.AreEqual(resourceCount, semaphore.CurrentCount); }
public void SingleThread() { var semaphore = new LockFreeSemaphore(0, 3); Assert.AreEqual(0, semaphore.CurrentCount); semaphore.Release(); Assert.AreEqual(1, semaphore.CurrentCount); semaphore.Release(2); Assert.AreEqual(3, semaphore.CurrentCount); Assert.Throws<SemaphoreFullException>(semaphore.Release); Assert.IsTrue(semaphore.TryTake()); Assert.AreEqual(2, semaphore.CurrentCount); Assert.IsTrue(semaphore.TryTake()); Assert.IsTrue(semaphore.TryTake()); Assert.AreEqual(0, semaphore.CurrentCount); Assert.IsFalse(semaphore.TryTake()); Assert.AreEqual(0, semaphore.CurrentCount); }