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


Синтаксис обработчика завершения

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

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

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

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

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

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

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

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

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

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

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

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