ReaderWriterLockSlim и конструкция await using решают разные задачи в контексте многопоточного и асинхронного программирования в C#.
ReaderWriterLockSlim предназначен для координации доступа к ресурсу между разными потоками, позволяя множественный доступ на чтение и эксклюзивный доступ на запись. Это синхронизирующий примитив, который обеспечивает блокировку и требует явного снятия блокировки. В асинхронных операциях его использовать не рекомендуется, так как он не поддерживает асинхронные ожидания и может приводить к блокировке потока.
Конструкция `await using` используется для автоматического освобождения асинхронных ресурсов, которые реализуют интерфейс `IAsyncDisposable` . Это часть управления ресурсами и обеспечения их корректного освобождения после завершения использования, что важно в асинхронном коде.
Ваш код вызывает `SynchronizationLockException` по следующей причине:
1. Дело в том, что контекст, в котором была захвачена блокировка с помощью ReaderWriterLockSlim, изменяется при выполнении асинхронной операции `await`. По завершении асинхронной операции `await` следующий код может уже выполняться в другом контексте (в другом потоке), где блокировка никогда не захватывалась, и это приводит к исключению, потому что ReaderWriterLockSlim разрешает выходить из блокировки только в том же потоке, что и заходить в нее.
2. Ошибка возникает при попытке вызова `rwl.ExitWriteLock()` в блоке `finally`, если блокировка была захвачена в одном контексте (потоке), но попытка снять блокировку происходит в другом из-за изменения контекста выполнения после `await`.
Чтобы исключить подобные исключения при использовании ReaderWriterLockSlim в асинхронном коде, необходимо обеспечить, чтобы `EnterWriteLock()` и соответствующий `ExitWriteLock()` выполнялись в одном и том же контексте. Либо не использовать ReaderWriterLockSlim в асинхронных методах вообще, а воспользоваться асинхронными примитивами синхронизации, например, `SemaphoreSlim` с асинхронной поддержкой или асинхронными ReaderWriterLock, такими как `AsyncReaderWriterLock`, которые предоставляются некоторыми библиотеками, но не включены в стандартную библиотеку .NET.