С# - Заблокировать вопрос с помощью EnterWriteLock
Следующий код из MSDN:
private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim();
private Dictionary<int, string> innerCache = new Dictionary<int, string>();
public void Add(int key, string value)
{
cacheLock.EnterWriteLock();
try
{
innerCache.Add(key, value);
}
finally
{
cacheLock.ExitWriteLock();
}
}
Я видел такой код в других местах. EnterWriteLock() всегда находится вне блока try. Кто-нибудь знает, почему это не внутри блока try?
Ответы
Ответ 1
Предположим, что EnterWriteLock()
терпит неудачу. Для любой причины.
Тогда одна вещь, которую вы не должны делать, это выйти из блокировки, которую вы никогда не вводили.
Это очень простой шаблон, который также имеет место, например, для потоков, но не часто рассматривается благодаря оператору using() {}
.
var s = File.Create(...);
// (only) if the previous line succeeded,
// we gain the responsibility to close s, no matter what
try
{
// do some I/O
}
finally
{
s.Dispose();
}
Ответ 2
Потому что это будет ошибка. Вы не можете позвонить в ExitWriteLock, пока не убедитесь, что вы ввели его. Представьте, что произойдет, если вы переместили его внутри try {} и EnterWriteLock() выдает исключение. Это двойная кабума. Kabloom, привинчивает сообщение об исключении.
Ответ 3
Если EnterWriteLock выдает исключение, нет необходимости вызывать ExitWriteLock, поэтому причина не в блоке try. ExitWriteLock всегда следует вызывать, если EnterWriteLock успешно вызван. Возможно, вы захотите обернуть блок try вокруг EnterWriteLock в определенных сценариях, поскольку он может вызвать исключение LockRecursionException. ExitWriteLock также может генерировать исключение SynchronizationLockException и может потребовать блок try в вашем приложении.