public void No_deadlock_and_no_race_condition_on_resources()
        {
            var mgr = new LockManager();

            var watch = new Stopwatch();

            watch.Start();

            int iterations = 10_000;

            Parallel.For(0, iterations, i =>
            {
                Parallel.Invoke(
                    () => mgr.DoWithReadLock(ReadAbc, "a", "b", "c"),
                    () => mgr.DoWithReadLock(ReadA, "a"),
                    () => mgr.DoWithWriteLock(WriteAbc, "a", "b", "c"),
                    () => mgr.DoWithWriteLock(WriteA, "a")
                    );
            });

            watch.Stop();

            Console.WriteLine($"{iterations} iterations took {watch.ElapsedMilliseconds} ms");
            Console.WriteLine($"retries = {mgr.Retries}");
            Console.WriteLine($"a = {_resourceA.Count} b = {_resourceB.Count} c = {_resourceC.Count}");


            int locks = mgr.GetCurrentlyHoldLocks();

            Assert.AreEqual(0, locks);
        }
        public void Mixed_use_of_sessions_and_simple_accesses_simulating_both_transactional_and_non_transactional_clients()
        {
            var mgr = new LockManager();

            var watch = new Stopwatch();

            watch.Start();



            int iterations = 100;

            Parallel.For(0, iterations, i =>
            {
                Parallel.Invoke(
                    () =>
                {
                    for (int i = 0; i < iterations; i++)
                    {
                        var session = Guid.NewGuid();
                        mgr.AcquireLock(session, false, "a", "b", "c");
                        ReadAbc();
                        mgr.CloseSession(session);
                    }
                },
                    () =>
                {
                    for (int i = 0; i < iterations; i++)
                    {
                        var session = Guid.NewGuid();
                        mgr.AcquireLock(session, false, "a");
                        ReadA();
                        mgr.CloseSession(session);
                    }
                },
                    () =>
                {
                    for (int i = 0; i < iterations; i++)
                    {
                        var session = Guid.NewGuid();
                        mgr.AcquireLock(session, true, "a", "b", "c");
                        WriteAbc();
                        mgr.CloseSession(session);
                    }
                },
                    () =>
                {
                    for (int i = 0; i < iterations; i++)
                    {
                        var session = Guid.NewGuid();
                        mgr.AcquireLock(session, true, "a");
                        WriteA();
                        mgr.CloseSession(session);
                    }
                },
                    () =>
                {
                    for (int i = 0; i < 100; i++)
                    {
                        mgr.DoWithReadLock(ReadAbc, "a", "b", "c");
                    }
                },
                    () =>
                {
                    for (int i = 0; i < 100; i++)
                    {
                        mgr.DoWithReadLock(ReadA, "a");
                    }
                },
                    () =>
                {
                    for (int i = 0; i < 100; i++)
                    {
                        mgr.DoWithWriteLock(WriteAbc, "a", "b", "c");
                    }
                },
                    () =>
                {
                    for (int i = 0; i < 100; i++)
                    {
                        mgr.DoWithWriteLock(WriteA, "a");
                    }
                });
            });

            watch.Stop();

            Console.WriteLine($"{iterations} iterations took {watch.ElapsedMilliseconds} ms");
            Console.WriteLine($"retries = {mgr.Retries}");
            Console.WriteLine($"a = {_resourceA.Count} b = {_resourceB.Count} c = {_resourceC.Count}");


            int locks = mgr.GetCurrentlyHoldLocks();

            Assert.AreEqual(0, locks);
        }