public void EnterExit()
        {
            using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim())
            {
                Assert.IsFalse(rwls.IsReadLockHeld);
                rwls.EnterReadLock();
                Assert.IsTrue(rwls.IsReadLockHeld);
                rwls.ExitReadLock();
                Assert.IsFalse(rwls.IsReadLockHeld);

                Assert.IsFalse(rwls.IsUpgradeableReadLockHeld);
                rwls.EnterUpgradeableReadLock();
                Assert.IsTrue(rwls.IsUpgradeableReadLockHeld);
                rwls.ExitUpgradeableReadLock();
                Assert.IsFalse(rwls.IsUpgradeableReadLockHeld);

                Assert.IsFalse(rwls.IsWriteLockHeld);
                rwls.EnterWriteLock();
                Assert.IsTrue(rwls.IsWriteLockHeld);
                rwls.ExitWriteLock();
                Assert.IsFalse(rwls.IsWriteLockHeld);

                Assert.IsFalse(rwls.IsUpgradeableReadLockHeld);
                rwls.EnterUpgradeableReadLock();
                Assert.IsFalse(rwls.IsWriteLockHeld);
                Assert.IsTrue(rwls.IsUpgradeableReadLockHeld);
                rwls.EnterWriteLock();
                Assert.IsTrue(rwls.IsWriteLockHeld);
                rwls.ExitWriteLock();
                Assert.IsFalse(rwls.IsWriteLockHeld);
                Assert.IsTrue(rwls.IsUpgradeableReadLockHeld);
                rwls.ExitUpgradeableReadLock();
                Assert.IsFalse(rwls.IsUpgradeableReadLockHeld);

                Assert.IsTrue(rwls.TryEnterReadLock(0));
                rwls.ExitReadLock();

                Assert.IsTrue(rwls.TryEnterReadLock(Timeout2.InfiniteTimeSpan));
                rwls.ExitReadLock();

                Assert.IsTrue(rwls.TryEnterUpgradeableReadLock(0));
                rwls.ExitUpgradeableReadLock();

                Assert.IsTrue(rwls.TryEnterUpgradeableReadLock(Timeout2.InfiniteTimeSpan));
                rwls.ExitUpgradeableReadLock();

                Assert.IsTrue(rwls.TryEnterWriteLock(0));
                rwls.ExitWriteLock();

                Assert.IsTrue(rwls.TryEnterWriteLock(Timeout2.InfiniteTimeSpan));
                rwls.ExitWriteLock();
            }
        }
        public void InvalidTimeouts()
        {
            using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim())
            {
                AssertExtensions.Throws <ArgumentOutOfRangeException>(() => rwls.TryEnterReadLock(-2));
                AssertExtensions.Throws <ArgumentOutOfRangeException>(() => rwls.TryEnterUpgradeableReadLock(-3));
                AssertExtensions.Throws <ArgumentOutOfRangeException>(() => rwls.TryEnterWriteLock(-4));

                AssertExtensions.Throws <ArgumentOutOfRangeException>(() => rwls.TryEnterReadLock(TimeSpan.MaxValue));
                AssertExtensions.Throws <ArgumentOutOfRangeException>(() => rwls.TryEnterUpgradeableReadLock(TimeSpan.MinValue));
                AssertExtensions.Throws <ArgumentOutOfRangeException>(() => rwls.TryEnterWriteLock(TimeSpan.FromMilliseconds(-2)));
            }
        }
        public void Dispose()
        {
            ReaderWriterLockSlim rwls;

            rwls = new ReaderWriterLockSlim();
            rwls.Dispose();
            AssertExtensions.Throws <ObjectDisposedException>(() => rwls.TryEnterReadLock(0));
            AssertExtensions.Throws <ObjectDisposedException>(() => rwls.TryEnterUpgradeableReadLock(0));
            AssertExtensions.Throws <ObjectDisposedException>(() => rwls.TryEnterWriteLock(0));
            rwls.Dispose();

            for (int i = 0; i < 3; i++)
            {
                rwls = new ReaderWriterLockSlim();
                switch (i)
                {
                case 0: rwls.EnterReadLock(); break;

                case 1: rwls.EnterUpgradeableReadLock(); break;

                case 2: rwls.EnterWriteLock(); break;
                }
                AssertExtensions.Throws <SynchronizationLockException>(() => rwls.Dispose());
            }
        }
 public void WriterToUpgradeableReaderChain()
 {
     using (AutoResetEvent are = new AutoResetEvent(false))
         using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim())
         {
             rwls.EnterWriteLock();
             Task t = Task.Factory.StartNew(() =>
             {
                 Assert.IsFalse(rwls.TryEnterUpgradeableReadLock(TimeSpan.FromMilliseconds(10)));
                 Task.Run(() => are.Set()); // ideally this won't fire until we've called EnterReadLock, but it's a benign race in that the test will succeed either way
                 rwls.EnterUpgradeableReadLock();
                 rwls.ExitUpgradeableReadLock();
             }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
             are.WaitOne();
             rwls.ExitWriteLock();
             t.GetAwaiter().GetResult();
         }
 }