Выполняет ли ThreadAbortException принудительное выполнение кода в секции finally (try / catch)? - PullRequest
5 голосов
/ 23 мая 2011

У меня есть таймер System.Timers.Timer, для которого AutoReset установлен на false. Я использую try/finally, чтобы застраховать I Start таймер в конце его callback (я использую таймер таким образом, чтобы предотвратить наложение выполнения callback). Код:

// inside timer call back
try
{
    // Do something
}
finally
{
    timer.Start(); // Is this line always executed?
}

Мой вопрос: что произойдет, если поток выполнения будет Aborted? Секция finally все еще выполняется или нет потока для выполнения этой части?

Ответы [ 5 ]

6 голосов
/ 23 мая 2011

Официальный источник ...

Когда вызывается метод Abort для уничтожения потока, общеязыковая среда выполнения выдает исключение ThreadAbortException.ThreadAbortException - это особое исключение, которое может быть перехвачено, но оно будет автоматически вызвано снова в конце блока catch.Когда возникает это исключение, среда выполнения выполняет все блоки finally перед завершением потока.Поскольку поток может выполнять неограниченные вычисления в блоках finally или вызывать Thread.ResetAbort для отмены прерывания, нет гарантии, что поток когда-нибудь закончится.Если вы хотите дождаться окончания прерванного потока, вы можете вызвать метод Thread.Join.Присоединение - это блокирующий вызов, который не возвращается, пока поток фактически не прекратит выполнение.

Подробнее об этом можно узнать на MSDN .

4 голосов
/ 23 мая 2011

Квотирование документации (empahsis mine):

Когда этот метод вызывается в потоке, система генерирует исключение ThreadAbortException в потоке, чтобы прервать его.ThreadAbortException - это специальное исключение, которое может быть перехвачено кодом приложения, но повторно генерируется в конце блока catch, если не вызывается ResetAbort.ResetAbort отменяет запрос на прерывание и предотвращает завершение потока в ThreadAbortException. Неисполненные блоки finally выполняются до прерывания потока.

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

Таким образом, ответ - да,наконец блоки будут выполнены.

4 голосов
/ 23 мая 2011

Да, эта строка всегда будет выполняться, и прерывание будет заблокировано, пока не завершится код в предложении finally.

1 голос
/ 22 июня 2013

, если поток уже был прерван, блок catch и блок finally могут продолжать выполняться.

Пожалуйста, перейдите по этой ссылке, чтобы получить четкое представление о том, как она обрабатывается в классе system.threading. Канализация глубины резьбыAbortException

1 голос
/ 23 мая 2011

Да, finally всегда будет использоваться независимо от того, как он выходит из try,

 Whereas catch is used to handle exceptions that occur in a statement block, 
 finally is used to guarantee a statement block of code executes regardless 
 of how the preceding try block is exited.

Подробнее об этом MSDN .

...