/// <summary> /// Completes the collection /// </summary> /// <returns>A Task that completes when the collection is empty</returns> /// <remarks> /// <para>This is safe to call multiple times</para> /// <para>Any pending <see cref="O:Add" /> calls may complete successfully. Any future <see cref="O:Add" /> calls will return False</para> /// <para>Any pending or future <see cref="O:Take" /> calls will return the contents of the collection until it is empty, before throwing <see cref="InvalidOperationException"/>.</para> /// <para>If the collection is empty at this point, pending <see cref="O:Take" /> calls will immediately throw <see cref="InvalidOperationException"/>.</para> /// <para>If a consumer is currently waiting on a task retrieved via <see cref="O:GetConsumingEnumerable" /> and the collection is empty, the task will throw <see cref="InvalidOperationException"/>.</para> /// </remarks> public ValueTask CompleteAdding() { // New Add operations will now fail. Take operations will fail once the collection is empty var Used = _UsedSlots.DisposeAsync(); if (_FreeSlots != null) { // Pending Add operations will now fail. _FreeSlots.DisposeAsync(); } return(Used); }
public async Task DisposeTryDecrementAsync() { //**************************************** var MyLock = new AsyncCounter(); //**************************************** _ = MyLock.DisposeAsync(); Assert.IsFalse(await MyLock.TryDecrementAsync()); //**************************************** Assert.AreEqual(0, MyLock.WaitingCount, "Waiter still registered"); Assert.AreEqual(0, MyLock.CurrentCount, "Count not zero"); }
public void DisposeDecrement() { //**************************************** var MyLock = new AsyncCounter(); //**************************************** MyLock.DisposeAsync(); Assert.ThrowsAsync <ObjectDisposedException>(() => MyLock.Decrement().AsTask()); //**************************************** Assert.AreEqual(0, MyLock.WaitingCount, "Waiter still registered"); Assert.AreEqual(0, MyLock.CurrentCount, "Count not zero"); }
public void IncrementDispose() { //**************************************** var MyLock = new AsyncCounter(); //**************************************** MyLock.Increment(); var DisposeTask = MyLock.DisposeAsync(); Assert.IsFalse(DisposeTask.IsCompleted, "Dispose completed early"); //**************************************** Assert.AreEqual(0, MyLock.WaitingCount, "Waiter still registered"); Assert.AreEqual(1, MyLock.CurrentCount, "Count not one"); }
public void IncrementDisposeTryDecrement() { //**************************************** var MyLock = new AsyncCounter(); //**************************************** MyLock.Increment(); _ = MyLock.DisposeAsync(); Assert.IsTrue(MyLock.TryDecrement()); Assert.IsFalse(MyLock.TryDecrement()); //**************************************** Assert.AreEqual(0, MyLock.WaitingCount, "Waiter still registered"); Assert.AreEqual(0, MyLock.CurrentCount, "Count not zero"); }
public void DisposeIncrement() { //**************************************** var MyLock = new AsyncCounter(); //**************************************** MyLock.DisposeAsync(); try { MyLock.Increment(); Assert.Fail("Should never reach this point"); } catch (ObjectDisposedException) { } //**************************************** Assert.AreEqual(0, MyLock.WaitingCount, "Waiter still registered"); Assert.AreEqual(0, MyLock.CurrentCount, "Count not zero"); }