Параллельная работа обработчиков исключений

Обработчику исключения — catch-блоку, захватившему исключение, — передается текущее исключение. Анализируя свойства этого объекта, обработчик может понять причину, приведшую к возникновению исключительной ситуации, попытаться ее исправить и в случае успеха продолжить вычисления. Заметьте, в принятой C# схеме без возобновления обработчик исключения не возвращает управление try-блоку, а сам пытается решить проблемы. После завершения catch-блока выполняются операторы текущего метода, следующие за конструкцией try-catch-finally.

Зачастую обработчик исключения не может исправить ситуацию или может выполнить это лишь частично, предоставив решение оставшейся части проблем вызвавшему методу — предшественнику в цепочке вызовов. Механизм, реализующий такую возможность — это тот же механизм исключений. Как правило, в конце своей работы обработчик исключения выбрасывает исключение, выполняя оператор throw. При этом у него есть две возможности: повторно выбросить текущее исключение или выбросить новое исключение, содержащее дополнительную информацию.

Таким образом, обработку возникшей исключительной ситуации могут выполнять несколько обработчиков, принадлежащие разным уровням цепочки вызовов.

Блок finally

До сих пор ничего не было сказано о важном участнике схемы обработки исключений — блоке finally. Напомню, рассматриваемая схема является схемой без возобновления. Это означает, что управление вычислением неожиданно покидает try-блок. Просто так этого делать нельзя — нужно выполнить определенную чистку. Прежде всего удаляются все локальные объекты, созданные в процессе работы блока. В языке С++ эта работа требовала вызова деструкторов объектов. В C#, благодаря автоматической сборке мусора, освобождением памяти можно не заниматься, достаточно освободить стек. Но в блоке try могли быть заняты другие ресурсы — открыты файлы, захвачены некоторые устройства. Освобождение ресурсов, занятых try-блоком, выполняет finally-блок. Если он присутствует, он выполняется всегда, сразу же после завершения работы try-блока, как бы последний ни завершился. Блок try может завершиться вполне нормально без всяких происшествий и управление достигнет конца блока, выполнение может быть прервано оператором throw, управление может быть передано другому блоку из-за выполнения таких операторов как goto, return — во всех этих случаях, прежде чем управление будет передано по предписанному назначению (в том числе, прежде чем произойдет захват исключения ), предварительно будет выполнен finally-блок, который освобождает

ресурсы, занятые try-блоком, а параллельно будет происходить освобождение стека от локальных переменных.

Оставить комментарий

avatar
  Подписаться  
Уведомление о