public void TestReadWriteLock_NonConcurrent()
        {
            using (var rwlock = new ReadWriteLock())
            {
                using (rwlock.EnterReadScope()) { }
                using (rwlock.EnterWriteScope()) { }
                using (rwlock.EnterUpgradeableReadScope())
                using (rwlock.EnterWriteScope()) { }

                rwlock.Dispose();
            }
        }
        public void TestReadWriteLock_NoWriteWhileReading()
        {
            // ReSharper disable AccessToModifiedClosure
            // ReSharper disable AccessToDisposedClosure
            // ReSharper disable ImplicitlyCapturedClosure
            using (var rwlock = new ReadWriteLock())
            {
                string value = "foo";

                const string expected = "foo";
                string actual = null;

                var ewh1 = new EventWaitHandle(false, EventResetMode.ManualReset);
                var ewh2 = new EventWaitHandle(false, EventResetMode.ManualReset);

                var task1 = Task.Factory.StartNew(() =>
                {
                    using (rwlock.EnterReadScope())
                    {
                        ewh1.Set();
                        Assert.False(ewh2.WaitOne(TimeSpan.FromMilliseconds(100)));
                        Thread.Sleep(100);

                        actual = value;
                    }
                    Assert.True(ewh2.WaitOne(TimeSpan.FromSeconds(5)));
                });

                var task2 = Task.Factory.StartNew(() =>
                {
                    Assert.True(ewh1.WaitOne(TimeSpan.FromSeconds(5)));
                    using (rwlock.EnterWriteScope())
                        value = "bar";
                    ewh2.Set();
                });

                Assert.True(task1.Wait(TimeSpan.FromSeconds(5)));
                Assert.True(task2.Wait(TimeSpan.FromSeconds(5)));

                Assert.AreEqual(expected, actual);
            }
            // ReSharper restore ImplicitlyCapturedClosure
            // ReSharper restore AccessToDisposedClosure
            // ReSharper restore AccessToModifiedClosure
        }