Если блок finally создает исключение, что именно происходит?
В частности, что происходит, если исключение выдается на полпути через блок finally. Вызваны ли остальные операторы (после) в этом блоке?
Я знаю, что исключения будут распространяться вверх.
c#
exception
exception-handling
try-catch-finally
Джек Када
источник
источник
Ответы:
Это исключение распространяется вверх и вверх и будет (может) обрабатываться на более высоком уровне.
Ваш блок finally не будет завершен после того, как будет сгенерировано исключение.
Если блок finally выполнялся во время обработки более раннего исключения, то это первое исключение теряется.
источник
ThreadAbortException
, тогда весь блок finally будет закончен первым, так как это критический раздел.Для таких вопросов я обычно открываю пустой проект консольного приложения в Visual Studio и пишу небольшой пример программы:
При запуске программы вы увидите точный порядок, в котором
catch
иfinally
выполняются блоки. Обратите внимание, что код в блоке finally после создания исключения не будет выполнен (фактически, в этом примере программы Visual Studio даже предупредит вас, что обнаружил недоступный код):Дополнительное замечание
Как отметил Михаил Даматов, исключение из
try
блока будет «съедено», если вы не обработаете его во (внутреннем)catch
блоке. Фактически, в приведенном выше примере повторно выброшенное исключение не появляется во внешнем блоке перехвата. Чтобы сделать это еще более понятным, взгляните на следующий слегка измененный пример:Как видно из вывода, внутреннее исключение «потеряно» (т.е. проигнорировано):
источник
finally
блок будет (почти) всегда выполняться, это также относится и к внутреннему блоку finally (просто попробуйте пример программы самостоятельно (блок finally не будет выполнен в случае невосстановимого). исключение, например, anEngineExecutionException
, но в таком случае ваша программа будет немедленно прервана в любом случае).Если есть ожидающее исключение (когда
try
блок имеет,finally
но нетcatch
), новое исключение заменяет это.Если нет ожидающих исключений, оно работает так же, как и исключение вне
finally
блока.источник
catch
блок , который (перо) вызывает исключение.Исключение распространяется.
источник
Быстрый (и довольно очевидный) фрагмент для сохранения «оригинального исключения» (брошенного в
try
блоке) и принесения в жертву «окончательного исключения» (брошенного вfinally
блоке), в случае, если для вас важнее оригинальное:Когда приведенный выше код выполняется, «Исходное исключение» распространяется вверх по стеку вызовов, а «Окончательное исключение» теряется.
источник
Я должен был сделать это для ловли ошибки, пытаясь закрыть поток, который никогда не был открыт из-за исключения.
если webRequest был создан, но во время
тогда, наконец, ловит исключение, пытаясь закрыть соединения, которые, по его мнению, были открыты, потому что был создан веб-запрос.
Если, наконец, не было try-catch внутри, этот код вызовет необработанное исключение при очистке webRequest
оттуда код будет завершен без надлежащей обработки возникшей ошибки и, следовательно, возникновения проблем для вызывающего метода.
Надеюсь, это поможет в качестве примера
источник
Создание исключения, когда другое исключение активно, приведет к тому, что первое исключение будет заменено вторым (более поздним) исключением.
Вот некоторый код, который иллюстрирует, что происходит:
источник
Несколько месяцев назад я тоже столкнулся с чем-то вроде этого,
Чтобы решить такую проблему, я сделал такой класс:
И используется так
но если вы хотите использовать параметры и возвращаемые типы, это другая история
источник
Способ обработки исключений, выданных CodeA и CodeB, одинаков.
Исключение, выброшенное в
finally
блоке, не имеет ничего особенного, рассматривайте его как исключение, генерируемое кодом B.источник
Исключение распространяется вверх и должно обрабатываться на более высоком уровне. Если исключение не обрабатывается на более высоком уровне, приложение вылетает. Выполнение блока finally останавливается в точке, где выдается исключение.
Независимо от того, есть ли исключение или нет, блок "finally" гарантированно будет выполнен.
Если блок finally выполняется после возникновения исключения в блоке try,
и если это исключение не обрабатывается
и если блок finally создает исключение
Тогда исходное исключение, которое произошло в блоке try, теряется.
Отличная статья для деталей
источник
Выдает исключение;) Вы можете перехватить это исключение в другом предложении catch.
источник