When using ReaderWriterLock and ReaderWriterLockSlim for managing read and write locks, you should not release a read lock while holding a write lock and vice versa, otherwise you might have runtime exceptions. The locks should be always correctly paired so that the shared resource is accessed safely.

This rule raises if:

- you call ReaderWriterLock.AcquireWriterLock or ReaderWriterLock.UpgradeToWriterLock and then use ReaderWriterLock.ReleaseReaderLock
- you call ReaderWriterLockSlim.EnterWriteLock or ReaderWriterLockSlim.TryEnterWriteLock and then use ReaderWriterLockSlim.ExitReadLock
- you call ReaderWriterLock.AcquireReaderLock or ReaderWriterLock.DowngradeFromWriterLock and then use ReaderWriterLock.ReleaseWriterLock
- or you call ReaderWriterLockSlim.EnterReadLock, ReaderWriterLockSlim.TryEnterReadLock, ReaderWriterLockSlim.EnterUpgradeableReadLock or ReaderWriterLockSlim.TryEnterUpgradeableReadLock and then use ReaderWriterLockSlim.ExitWriteLock

## Why is this an issue?

If you use the `ReaderWriterLockSlim` class, you will get a LockRecursionException. In the case of `ReaderWriterLock`, you’ll get a runtime exception for trying to release a lock that is not owned by the calling thread.

### Code examples

#### Noncompliant code example

    public class Example
    {
        private static ReaderWriterLock rwLock = new();

        public void Writer()
        {
            rwLock.AcquireWriterLock(2000);
            try
            {
                // ...
            }
            finally
            {
                rwLock.ReleaseReaderLock(); // Noncompliant, will throw runtime exception
            }
        }

        public void Reader()
        {
            rwLock.AcquireReaderLock(2000);
            try
            {
                // ...
            }
            finally
            {
                rwLock.ReleaseWriterLock(); // Noncompliant, will throw runtime exception
            }
        }
    }

#### Compliant solution

    public class Example
    {
        private static ReaderWriterLock rwLock = new();

        public static void Writer()
        {
            rwLock.AcquireWriterLock(2000);
            try
            {
                // ...
            }
            finally
            {
                rwLock.ReleaseWriterLock();
            }
        }

        public static void Reader()
        {
            rwLock.AcquireReaderLock(2000);
            try
            {
                // ...
            }
            finally
            {
                rwLock.ReleaseReaderLock();
            }
        }
    }

## Resources

### Documentation

- Microsoft Learn - ReaderWriterLock Class
- Microsoft Learn - ReaderWriterLockSlim