Я отмечаю, что никто не упомянул в своих ответах на этот старый вопрос, что снятие блокировки на исключение - невероятно опасная вещь. Да, операторы блокировки в C # имеют семантику "finally"; когда управление выходит из замка нормально или ненормально, замок снимается. Вы все говорите об этом, как будто это хорошо, но это плохо! Если у вас есть заблокированная область, которая генерирует необработанное исключение, нужно сделать следующее: немедленно прекратить больной процесс, прежде чем он уничтожит больше пользовательских данных , а не снять блокировку и продолжить работу .
Посмотрите на это так: предположим, у вас есть ванная комната с замком на двери и ряд людей, ожидающих снаружи. Взрывается бомба в ванной, убивает человека там. Ваш вопрос: «В этой ситуации замок будет автоматически разблокирован, чтобы следующий человек мог войти в ванную?» Да, это будет. Это нехорошо. Там взорвалась бомба и убила кого-то! Сантехника, вероятно, разрушена, дом более не имеет конструктивной прочности, и там может быть еще одна бомба . Правильнее всего будет вывести всех как можно быстрее и снести весь дом.
Я имею в виду, продумайте это: если вы заблокировали область кода для чтения из структуры данных, не изменяя ее в другом потоке, и что-то в этой структуре данных вызвало исключение, шансы хороши, что это потому, что структура данных повреждена . Пользовательские данные теперь испорчены; Вы не хотите пытаться сохранить пользовательские данные на этом этапе, потому что тогда вы сохраняете поврежденные данные. Просто прекратите процесс.
Если вы заблокировали область кода для того, чтобы выполнить мутацию без одновременного чтения состояния другим потоком и выбросить мутацию, тогда , если данные не были повреждены раньше, теперь это точно . Именно в этом сценарии предполагается, что блокировка должна защищать от . Теперь коду, ожидающему чтения этого состояния, будет немедленно предоставлен доступ к поврежденному состоянию, и, возможно, сам сбой. Опять же, правильное решение - прекратить процесс.
Независимо от того, как вы его нарезаете, исключение внутри замка - плохие новости . Правильный вопрос: «Будет ли мой замок очищен в случае исключения?» Правильный вопрос, который нужно задать: «Как я могу гарантировать, что в блокировке никогда не будет исключения? И если есть, то как мне структурировать мою программу так, чтобы мутации возвращались к предыдущим хорошим состояниям?»