public async Task RecursiveAsyncLock_DoesNotPermitIndependentWaits()
        {
            var mutex0 = new RecursiveAsyncLock();

            using (await mutex0.LockAsync())
            {
                var mutex = new RecursiveAsyncLock();
                Func <TaskCompletionSource, TaskCompletionSource, Task> taker = async(ready, finish) =>
                {
                    Assert.IsFalse(AsyncLockTracker.Contains(mutex));
                    using (await mutex.LockAsync())
                    {
                        Assert.IsTrue(AsyncLockTracker.Contains(mutex));
                        ready.TrySetResult();
                        await finish.Task;
                        Assert.IsTrue(AsyncLockTracker.Contains(mutex));
                    }
                    Assert.IsFalse(AsyncLockTracker.Contains(mutex));
                };

                var ready1  = new TaskCompletionSource();
                var finish1 = new TaskCompletionSource();
                Assert.IsFalse(AsyncLockTracker.Contains(mutex));
                var task1 = taker(ready1, finish1);
                Assert.IsFalse(AsyncLockTracker.Contains(mutex));
                await Task.WhenAny(ready1.Task, task1);

                Assert.IsFalse(AsyncLockTracker.Contains(mutex));

                var ready2  = new TaskCompletionSource();
                var finish2 = new TaskCompletionSource();
                Assert.IsFalse(AsyncLockTracker.Contains(mutex));
                var task2 = taker(ready2, finish2);
                Assert.IsFalse(AsyncLockTracker.Contains(mutex));

                Assert.IsFalse(ready2.Task.Wait(1000));

                finish1.SetResult();
                await Task.WhenAny(ready2.Task, task2);

                Assert.IsFalse(AsyncLockTracker.Contains(mutex));
                finish2.SetResult();
                await Task.WhenAll(task1, task2);

                Assert.IsFalse(AsyncLockTracker.Contains(mutex));
            }
        }
        public async Task RecursiveAsyncLock_PermitsRecursiveWaits()
        {
            var mutex = new RecursiveAsyncLock();

            Assert.IsFalse(AsyncLockTracker.Contains(mutex));
            var task1 = mutex.LockAsync();
            var key1  = await task1;

            Assert.IsTrue(AsyncLockTracker.Contains(mutex));

            var task2 = mutex.LockAsync();
            var key2  = await task2;

            Assert.IsTrue(AsyncLockTracker.Contains(mutex));

            key2.Dispose();
            Assert.IsTrue(AsyncLockTracker.Contains(mutex));
            key1.Dispose();
            Assert.IsFalse(AsyncLockTracker.Contains(mutex));
        }