public async Task LockMaxLockDispose()
        {               //****************************************
            var MyLock = new AsyncSemaphore();
            //****************************************

            var MyWait1 = MyLock.Take();

            var MyWait2 = MyLock.Take();

            var MyDispose = MyLock.DisposeAsync();

            try
            {
                (await MyWait2).Dispose();

                Assert.Fail("Did not dispose");
            }
            catch (ObjectDisposedException)
            {
            }

            MyWait1.Result.Dispose();

            //****************************************

            await MyDispose;

            Assert.AreEqual(0, MyLock.WaitingCount, "Still waiting for Semaphore");
            Assert.AreEqual(MyLock.MaxCount, MyLock.CurrentCount, "Semaphore still held");
        }
        public async Task TryTakeTakeTimeoutDispose()
        {               //****************************************
            var MyLock = new AsyncSemaphore(1);

            //****************************************

            Assert.True(MyLock.TryTake(out var MyHandle1), "Lock not taken");

            var MyTask = Task.Run(async() =>
            {
                await Task.Delay(50);

                await MyLock.DisposeAsync();
            });

            Assert.False(MyLock.TryTake(out var MyHandle2, TimeSpan.FromMilliseconds(100)), "Nested lock taken");

            MyHandle1.Dispose();

            await MyTask;

            //****************************************

            Assert.AreEqual(0, MyLock.WaitingCount, "Still waiting for Semaphore");
            Assert.AreEqual(MyLock.MaxCount, MyLock.CurrentCount, "Semaphore still held");
        }
        public async Task LockLockDispose()
        {               //****************************************
            var MyLock = new AsyncSemaphore(2);
            //****************************************

            var MyWait1 = MyLock.Take();

            var MyWait2 = MyLock.Take();

            var MyDispose = MyLock.DisposeAsync();

            Assert.IsFalse(MyDispose.IsCompleted, "Dispose completed early");

            MyWait2.Result.Dispose();

            Assert.IsFalse(MyDispose.IsCompleted, "Dispose completed early");

            MyWait1.Result.Dispose();

            //****************************************

            await MyDispose;

            Assert.AreEqual(0, MyLock.WaitingCount, "Still waiting for Semaphore");
            Assert.AreEqual(MyLock.MaxCount, MyLock.CurrentCount, "Semaphore still held");
        }
        public async Task Dispose()
        {               //****************************************
            var MyLock = new AsyncSemaphore();
            //****************************************

            await MyLock.DisposeAsync();

            //****************************************

            Assert.AreEqual(0, MyLock.WaitingCount, "Still waiting for Semaphore");
            Assert.AreEqual(MyLock.MaxCount, MyLock.CurrentCount, "Semaphore still held");
        }
        public async Task DisposeTryTakeZero()
        {               //****************************************
            var MyLock = new AsyncSemaphore();
            //****************************************

            var MyDispose = MyLock.DisposeAsync();

            Assert.False(MyLock.TryTake(out _, TimeSpan.Zero), "Nested lock taken");

            //****************************************

            await MyDispose;

            Assert.AreEqual(0, MyLock.WaitingCount, "Still waiting for Semaphore");
            Assert.AreEqual(MyLock.MaxCount, MyLock.CurrentCount, "Semaphore still held");
        }
        public void LockDisposeContinueWithLock()
        {               //****************************************
            var MyLock = new AsyncSemaphore();
            //****************************************

            var MyCounter = MyLock.Take().Result;

            var MyTask = MyLock.Take().AsTask();

            var MyInnerTask = MyTask.ContinueWith((task) => MyLock.Take().AsTask(), TaskContinuationOptions.ExecuteSynchronously).Unwrap();

            MyLock.DisposeAsync();

            //****************************************

            Assert.ThrowsAsync <ObjectDisposedException>(() => MyTask);
            Assert.ThrowsAsync <ObjectDisposedException>(() => MyInnerTask);
        }
        public async Task DisposeLock()
        {               //****************************************
            var MyLock = new AsyncSemaphore();
            //****************************************

            var MyDispose = MyLock.DisposeAsync();

            try
            {
                MyLock.Take().GetAwaiter().GetResult().Dispose();
            }
            catch (ObjectDisposedException)
            {
            }

            //****************************************

            await MyDispose;

            Assert.AreEqual(0, MyLock.WaitingCount, "Still waiting for Semaphore");
            Assert.AreEqual(MyLock.MaxCount, MyLock.CurrentCount, "Semaphore still held");
        }