Поделиться через


Синтаксис Termination-Handler

Ключевые слова __try и __finally используются для создания обработчика завершения. В следующем примере показана структура обработчика завершения.

__try 
{ 
    // guarded body of code 
 
} 
__finally 
{ 
    // __finally block 
 
}

Примеры см. в разделе Использование обработчика завершения.

Как и в обработчике исключений, как блок __try, так и блок __finally требуют фигурных скобок ({}), и использование инструкции goto goto для перехода в любо й блок запрещено.

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

Блок __finally выполняется всякий раз, когда поток управления покидает блок __try. Однако блок __finally не выполняется при вызове каких-либо из следующих функций в блоке __try: ExitProcess, ExitThreadили прерывание.

Блок __finally выполняется в контексте функции, в которой находится обработчик завершения. Это означает, что блок __finally может получить доступ к локальным переменным этой функции. Выполнение блока __finally может завершиться любым из следующих средств.

  • Выполнение последней инструкции в блоке и продолжение следующей инструкции
  • Использование инструкции элемента управления (возвращаемых, разрыва, продолжитьили goto)
  • Использование longjmp или переход к обработчику исключений

Если выполнение блока __try завершается из-за исключения, вызывающего блок обработки исключений обработчика исключений на основе кадра, __finally блок выполняется перед выполнением блока обработки исключений. Аналогичным образом вызов функции библиотеки времени выполнения longjmp C из блока __try приводит к выполнению блока __finally до возобновления выполнения в целевом объекте операции longjmp. Если выполнение блока __try завершается из-за инструкции элемента управления (возвращать, прерывать, продолжатьили goto), выполняется блок __finally.

Функцию аномального можно использовать в блоке __finally, чтобы определить, завершается ли блок __try последовательно— то есть достигается ли закрывающая скобка (}). Выход из блока __try из-за вызова longjmp, перехода к обработчику исключений или возврата, прерывания, продолжитьили оператор goto, считается ненормальным завершением. Обратите внимание, что сбой последовательного завершения приводит к тому, что система выполняет поиск по всем кадрам стека в обратном порядке, чтобы определить, должны ли вызываться обработчики завершения. Это может привести к снижению производительности из-за выполнения сотен инструкций.

Чтобы избежать ненормального завершения обработчика завершения, выполнение должно продолжаться до конца блока. Вы также можете выполнить инструкцию __leave. Оператор __leave позволяет немедленно прекратить __try блок без ненормального завершения и его штрафа за производительность. Проверьте документацию компилятора, чтобы определить, поддерживается ли инструкция __leave.

Если выполнение блока __finally завершается из-за возвращаемого оператора элемента управления, это эквивалентно goto закрывающей скобке в заключающей функции. Таким образом, включающая функция возвращается.