@oleg_ods
Объясните, пожалуйста, поведение следующего блока кода:
var rwl = new ReaderWriterLockSlim();
rwl.EnterWriteLock();
try
{
await using var stream = new FileStream("1.txt", FileMode.Create);
await using var writer = new StreamWriter(stream);
await writer.WriteLineAsync("test");
// здесь происходит выход из блокировки. Как так то?
}
finally
{
// SynchronizationLockException: The write lock is being released without being held
rwl.ExitWriteLock();
}
1. Почему снятие блокировки происходит в блоке try?
2. Почему такое поведение только при использовании await using?
Буду искренне благодарен за ссылку на документацию где можно почитать про это явление=)
Решения вопроса 1
@AshBlade
Это LOCK!!!!
Никогда не используй асинхронный код внутри критической секции. Че случилось:
1. Поток 1 взял лок
2. Зашел в крит. секцию
3. await перенес тебя в другой поток (например, 2)
4. Поток 2 (новый) возвращает блокировку — НО ОН ЕЕ НЕ ДЕРЖИТ
Никогда не используй асинхронный код внутри критической секции. Че случилось:
1. Поток 1 взял лок
2. Зашел в крит. секцию
3. await перенес тебя в другой поток (например, 2)
4. Поток 2 (новый) возвращает блокировку — НО ОН ЕЕ НЕ ДЕРЖИТ
Если не веришь — попробуй то же самое, но с помощью обычного lock { }
сделать. Тебя компилятор поругает
Ответы на вопрос 2
@Smilleey
Перенесите первые две строки в try.
@Isafu
var rwl = new ReaderWriterLockSlim();
rwl.EnterWriteLock();
try
{
await using var stream = new FileStream("1.txt", FileMode.Create);
await using var writer = new StreamWriter(stream);
await writer.WriteLineAsync("test");
}
finally
{
if (rwl.IsWriteLockHeld)
rwl.ExitWriteLock();
}