Хотя я согласен со многими из вышеприведенных комментариев, включая детализацию блокировки и сомнительную обработку исключений, этот вопрос является одним из подходов. Позвольте мне привести одну серьезную причину, по которой я предпочитаю использовать абстракцию try {} finally ...
У меня есть модель, очень похожая на вашу, за одним исключением. Я определил базовый интерфейс ILock и в нем я предоставил один метод с именем Acquire (). Метод Acquire () возвратил объект IDisposable, и в результате это означает, что пока объект, с которым я имею дело, имеет тип ILock, его можно использовать для создания области блокировки. Почему это важно?
Мы имеем дело с множеством различных механизмов блокировки и поведения. Ваш объект блокировки может иметь определенный тайм-аут, который использует. Ваша реализация блокировки может быть блокировкой монитора, блокировкой считывателя, блокировкой записи или блокировкой вращения. Однако с точки зрения вызывающей стороны все это не имеет значения, их волнует то, что контракт на блокировку ресурса выполняется и что блокировка делает это в соответствии с его реализацией.
interface ILock {
IDisposable Acquire();
}
class MonitorLock : ILock {
IDisposable Acquire() { ... acquire the lock for real ... }
}
Мне нравится ваша модель, но я бы подумал спрятать механизм блокировки от звонящего. FWIW, я измерил издержки использования метода по сравнению с try-finally, и накладные расходы на выделение одноразового объекта будут иметь 2-3% накладных расходов производительности.