Ответ 1
приведенный ниже код ведет себя как ожидалось в режиме .NET3.5 RELEASE без отладчика, но не в .NET4.5.1. Я что-то пропустил?
ПРИМЕЧАНИЕ. Я переоценил уровень undefined -ness этого поведения; спасибо комментатору Voo за указание на это. Я должен был вернуться к спецификации в первую очередь.
Да. CLR требуется по спецификации CLI для завершения программы, когда есть необработанное исключение. Требуется только запуск блоков finally, если обрабатывается исключение. Спецификация неясна в вопросе о том, требуется ли CLR, разрешено или запрещена выполнение блоков finally, когда есть необработанное исключение; безопасное предположение заключается в том, чтобы сказать, что это поведение undefined по спецификации, и это зависит от конкретной реализации.
CLR может выбрать запуск блоков finally для необработанных исключений или нет по своей прихоти. Многие люди считают, что CLR использует этот алгоритм: по исключению, подходите к стеку вызовов, выполняя, наконец, блоки, когда ищете, ищите обработчиков; если обработчик не найден, завершите процесс. CLR не требуется соответствовать этому алгоритму в программе с необработанным исключением. В частности, CLR разрешено определять черной магией, что нет обработчика исключений, и никогда не запускать никаких блоков finally. Независимо от того, решит ли он это сделать или нет в некоторых версиях CLR в некоторых случаях, я не знаю. Ни в коем случае нельзя полагаться на это поведение для правильности вашей программы, потому что программа с необработанным исключением неверна.
В спецификации также отмечается, что CLR может предложить предлагать начать отладчики или нет по своей прихоти. CLR не требуется делать то же самое в отладке или выпуске, и не требуется делать то же самое с версии на версию.
Проблема в том, что вы сформировали ожидание, основанное на прошлом опыте, но нет документации, в которой говорится, что прошлый опыт является основой для прогнозирования будущего. Скорее всего, наоборот; CLR разрешено изменять свое поведение на основе фазы луны, если она нравится, в программе, которая имеет необработанное исключение.
Если вы хотите, чтобы ваша программа вела себя предсказуемо, не бросайте необработанные исключения.
Итак, если я правильно вас понимаю, если есть еще один улов где-то вверх по течению, блок finally выполнит?
Нет, я этого не говорил. Пусть сломается.
Если в программе есть неперехваченное исключение, то поведение программы определяется реализацией. Каким бы ни было поведение, которое вы получили, и CLR находится в пределах своих прав на создание такого поведения. Это включает в себя как запуск блоков finally, так и запуск блоков finally.
Предположим, что нет неотображаемого исключения, и возникает исключение, и на пути к catch есть блок finally. Гарантируется ли выполнение блока finally? Нет. Есть много вещей, которые могут помешать окончательному блокированию от выполнения в юридической программе. Например, другой, наконец, блок или фильтр исключений по пути мог перейти в бесконечный цикл или быстрый сбой, любой из которых предотвратил бы выполнение блока finally. Если у вас АБСОЛЮТНО ПОЛОЖИТЕЛЬНО должен быть запущен какой-то код очистки, вам необходимо исследовать области ограничений. (Я не знаю, как они работают, мне никогда не приходилось учиться, я слышал, что они сложны.).
Гарантируется, что если элемент управления покидает защищенный окончательно блок, тогда будет запущен код finally. Выполнение кода во время фильтров исключений не считается выходящим из блока, а сбой при быстром не приводит к тому, что управление программой выходит из блока, это приводит к внезапному завершению управления программой. Очевидно, что бесконечные циклы вызывают контроль, чтобы никогда не выходить из блока.
Я полагаю, что в случае действительно необработанного исключения программа должна прекратиться в любом случае, так что сиротское соединение/транзакция БД не должно быть проблемой?
Является ли это проблемой или нет, я не могу сказать. Попросите автора вашей базы данных.
Очень вероятно, что программа завершится, хотя снова я отмечаю, что CLR не требуется для такого поведения. Предположим, например, существует некоторая нить, которая продолжает работать, пока CLR пытается выяснить, установлен ли у вас отладчик или нет. CLR находится в пределах своих прав, чтобы занять какое-то время, чтобы понять это, и, следовательно, в пределах своих прав поддерживать этот поток. Делает это или нет, я не знаю. Я знаю, что я не хочу полагаться на любое поведение.
Кроме того, использование "AppDomain.CurrentDomain.UnhandledException" считается "обработкой"
Неа. Если эта вещь выполняется, тогда было необработанное исключение, и поведение программы определяется реализацией. Этот обработчик событий должен использоваться только для того, чтобы делать такие вещи, как журнал, тот факт, что программа имеет ошибку.