Пара очков.
1) То, что вы хотите найти, это «одноразовый шаблон». Будьте очень осторожны, чтобы правильно реализовать . Конечно, Mutex уже реализует одноразовый шаблон, поэтому мне неясно, почему вы хотите создать свой собственный, но все же, о нем полезно узнать.
См. Этот вопрос для некоторых дополнительных мыслей о том, разумно ли использовать одноразовый шаблон, как если бы это был RAII:
Неправильно ли использовать IDisposable и «использование» в качестве средства для получения «ограниченного поведения» для обеспечения безопасности исключений?
2) Try-finally также имеет семантику, которую вы хотите. Конечно, блок "using" - это просто синтаксический сахар для try-finally.
3) Вы уверены, , что хотите освободить мьютекс, когда что-то выбрасывается? Вы уверены, что хотите бросить в защищенном регионе?
Это неприятный запах кода по следующей причине.
Почему у вас мьютекс? Обычно, потому что шаблон выглядит так:
- состояние соответствует, но устарел
- блокировка доступа к состоянию
- делает государство непоследовательным
- согласовать состояние
- разблокировать доступ к состоянию
- состояние теперь согласованно и свежо
Подумайте, что происходит, когда вы бросаете исключение перед тем, как «привести состояние в соответствие». Вы разблокируете доступ к состоянию, которое теперь является несовместимым и устаревшим .
Может быть, лучше сохранить блокировку . Да, это означает риск возникновения тупиковых ситуаций, но, по крайней мере, ваша программа не работает с мусором, устаревшим, несовместимым состоянием.
Это ужасная, ужасная вещь - выбросить исключение из защищенной замком области, и вам следует избегать этого, когда это возможно. Исключение, генерируемое изнутри блокировки, заставляет вас выбирать между двумя ужасными вещами: либо вы получаете тупики, либо вы получаете сумасшедшие сбои и невоспроизводимое поведение, когда ваша программа манипулирует несовместимым состоянием.
Шаблон, который вы действительно должны реализовать:
- состояние соответствует, но устарел
- блокировка доступа к состоянию
- делает государство непоследовательным
- согласовать состояние
- если возникает исключение, откатитесь в устаревшее согласованное состояние
- разблокировать доступ к состоянию
- состояние теперь соответствует и, если не было исключения, обновляется
Это гораздо более безопасная альтернатива, но писать код, который выполняет подобные транзакции, сложно. Никто не говорил, что многопоточность - это просто.