.Net Framework: блок finally не вызывается, если исключение не обнаружено

Простое консольное приложение в Visual Studio 2019, .Net Framework 4.7, Windows:

static void Main(string[] args)
{
    try
    {
         Console.WriteLine("In try");
         throw new IndexOutOfRangeException();
    }
    finally
    {        *// Surprisingly this part is not being executed.*
         Console.WriteLine("In finally");
         Console.ReadLine();
    }                       
}

Я был уверен, что блок finally вызывается как в случае NO Exception, так и в случае YES Exception. Я читал в документах:

Однако, если исключение не обрабатывается, выполнение блока finally зависит от того, как запускается операция очистки исключения. Это, в свою очередь, зависит от того, как настроен ваш компьютер.

Ссылка Что ж, я смущенный. Мне нужно что-то с этой операцией размотки, чтобы, наконец, было вызвано в случае необработанных исключений?


person S Itzik    schedule 30.11.2020    source источник
comment
this и this   -  person dontbyteme    schedule 30.11.2020
comment
Этот ответ Эрика Липпера должен прояснить это: stackoverflow.com/a/4196863/5311735   -  person Evk    schedule 30.11.2020
comment
Что я вижу после запуска этого кода: 1. В попытке 2. Необработанное исключение: ... 3. В конце концов | Так в чем проблема?   -  person SᴇM    schedule 30.11.2020
comment
@SM, вы должны прочитать вопрос еще раз, я также вставил его в dotnetfiddle и подумал: «ну, это просто работает», но здесь спрашивают не об этом.   -  person sommmen    schedule 30.11.2020
comment
@sem Вы запускали его в консольном приложении? Visual Studio 2019?   -  person S Itzik    schedule 30.11.2020
comment
@SItzik Да, видел.   -  person SᴇM    schedule 30.11.2020
comment
Также может зависеть от платформы. Это .NET Framework или Core? Какая ОС? (Framework, только что осознал, вы высказали это в вопросе, извините.)   -  person Fildor    schedule 30.11.2020
comment
@Evk и dontbyteme благодарим вас за ваши комментарии, но, как вы можете видеть по своим ссылкам, ответы не были приняты как ответы, и они мне тоже не помогают. Эрик объяснил, почему не следует запускать finally, так что же нам делать, чтобы запустить блок finally в случае необработанного исключения?   -  person S Itzik    schedule 30.11.2020
comment
@sommmen Я не уверен насчет других частей вопроса, но заголовок мне довольно понятен. Возможно, OP нужно отредактировать вопрос / заголовок, чтобы меньше запутывать читателей.   -  person SᴇM    schedule 30.11.2020
comment
что нам делать, чтобы запустить блок finally в случае необработанного исключения? Вы действительно хотите принудительно запустить блок finally или хотите запустить что-то в случае необработанного исключения? (См. Событие AppDomain.UnhandledException )   -  person Fildor    schedule 30.11.2020
comment
Эрик говорит, что нельзя полагаться на запуск блока finally при необработанном исключении. В некоторых случаях он может работать, в других - нет, поэтому вам следует поступать именно так - не полагаться на его запуск.   -  person Evk    schedule 30.11.2020
comment
@Fildor Хорошее замечание. Я добавил эти детали к вопросу и о том, какова цель: цель состоит в том, чтобы блок finally выполнялся независимо от того, было ли исключение или нет (обработанное или необработанное)   -  person S Itzik    schedule 30.11.2020
comment
Поскольку блок finally может не запускаться при необработанном исключении, но (и я выхожу в Интернет здесь) будет продолжаться, когда исключение будет обработано, почему бы вам просто не добавить пустой оператор catch, который улавливает все исключения?   -  person sommmen    schedule 30.11.2020
comment
Я не уверен в эффекте этого, но я бы попытался зарегистрировать обработчик для события UnhandledException и посмотреть, изменит ли это обработку блока finally.   -  person Fildor    schedule 30.11.2020
comment
Людям, использующим dotnetfiddle для проверки. попробуйте изменить версию компилятора с .net 4.7.2 на .net core 5 и обратите внимание, что в последнем блок finally действительно не запускается, как утверждает op   -  person sommmen    schedule 30.11.2020
comment
The goal is that finally block will run no matter if there was an exception or not (handled or unhandled) Вы не можете по определению. Если бы это было возможно, тогда это было бы гарантировано. Но это не гарантируется. Хорошо, теоретически это могло бы работать, даже если это не было гарантировано - но даже если бы это было так, вы не могли полагаться на его работу в будущем.   -  person mjwills    schedule 30.11.2020
comment
so what should we do in order to run the finally block in case of an Unhandled exception? Поймай его - чтобы повысить вероятность того, что он не останется без внимания.   -  person mjwills    schedule 30.11.2020
comment
Я хотел сказать, что он отлично работает на моей машине, но может не работать на другом, с другими конфигурациями. И, как здесь заявили многие люди, необработанное исключение - это другая ситуация, когда система может решить прекратить ваш процесс. Вы не можете ожидать, что блок finally будет работать, если вы, например, отключите / выключите компьютер во время выполнения кода try.   -  person SᴇM    schedule 30.11.2020
comment
@mjwills: да, добавление уловок сработает, но, похоже, это противоречит тому, что я думал наконец. Теперь я вижу, что на некоторых машинах это работает, на некоторых нет ... Страшно. Возьмем, к примеру, предложение using. Он создает закулисную попытку и, наконец, без уловки, чтобы обещать избавиться ... теперь, по нашему обсуждению, даже это не обещано ...   -  person S Itzik    schedule 30.11.2020
comment
теперь, согласно нашему обсуждению, даже это не обещано ... только в случае (полностью) необработанного исключения.   -  person Fildor    schedule 30.11.2020
comment
@SItzik Вам, вероятно, следует так думать - если ваша программа работает нормально, в этом случае всегда будет выполняться finally.   -  person SᴇM    schedule 30.11.2020
comment
@Fildor, да, под словом «обещано» я имел в виду в любом случае необработанные исключения или обработанные. Проблема в том, что на некоторых машинах это будет работать, а на некоторых - нет. Так что неточный вопрос.   -  person S Itzik    schedule 30.11.2020
comment
even this is not promised... Правильно.   -  person mjwills    schedule 30.11.2020
comment
@Fildor, yes by the word "promised", I meant "any way" Unhandled exceptions or handled. По определению вы знаете, что это не может работать, не на 100% - например, для переполнения стека. Таким образом, вы имеете дело с степенью уверенности, а не с абсолютной уверенностью.   -  person mjwills    schedule 30.11.2020
comment
И я даже не понимал, какие конфигурации мне нужно изменить на моей машине, чтобы блок finally вызывал в таком случае, как это было вызвано некоторыми пользователями здесь.   -  person S Itzik    schedule 30.11.2020
comment
And I didn't even understand what configs I need to change in my machine in order the finally block will be called in such a case, Кто сказал, что это связано с конфигурацией (я не вижу этого в документации)? Если вы хотите, чтобы вероятность выполнения была выше - добавьте catch.   -  person mjwills    schedule 30.11.2020
comment
@ mjwills Верно, и в случаях, когда я выключаю электричество, но я думал, что, по крайней мере, в простых случаях, наконец, будет сделано каким-либо образом, если код выйдет из блока try, а это, к сожалению, не так.   -  person S Itzik    schedule 30.11.2020
comment
На самом деле, вы не можете обещать выполнить любой код. Такова природа необработанных (= неожиданных) событий. Если в вашу машину ударит молния, никакой сложный механизм не сможет гарантировать выполнение любого кода ... Но я понимаю то, что, по вашему мнению, должно быть возможно достичь ...   -  person Fildor    schedule 30.11.2020
comment
but I thought that at least in simple cases И это действительно так, в простых случаях. Верх стека вызовов (например, Main) - спорно, просто ли это в таком случае.   -  person mjwills    schedule 30.11.2020
comment
@mjwills, я добавлю ловушки, а как насчет пункта using? он не использует улов. Только попробуй и наконец. По нашему заключению, я бы исключил, что за кулисами он будет использовать уловку, чтобы быть уверенным, что объект будет удален. Не так ли?   -  person S Itzik    schedule 30.11.2020
comment
@mjwills Это именно то, что я говорю. Предложение using не использует catch. Только попробуй и наконец. Итак, как мы можем быть уверены, что Dispose () будет вызван?   -  person S Itzik    schedule 30.11.2020
comment
@SItzik So how can we be sure the Dispose() is going to be called? Ты не можешь. Как я уже говорил ранее.   -  person mjwills    schedule 30.11.2020
comment
Этот ответ stackoverflow.com/questions/111597/, поэтому наше обсуждение не соответствует действительности.   -  person S Itzik    schedule 30.11.2020
comment
Справедливо ли сказать, что ответ, написанный 12 лет назад, возможно, не учитывал последствия работы в другой среде выполнения и / или другой ОС? Да, это было бы справедливо сказать.   -  person mjwills    schedule 30.11.2020
comment
Так что на самом деле нет смысла пытаться и, наконец, не использовать уловки.   -  person S Itzik    schedule 30.11.2020
comment
there is not really a point Иногда ремни безопасности не помогают пережить аварию. И все же я ношу один. Почему? Потому что обычно это так. Есть ограниченные ситуации, когда вам нужен улов. Если для вас это важно, используйте уловку в этих сценариях.   -  person mjwills    schedule 30.11.2020
comment
Как правило? если в таком простом случае не помогает, когда помогает? У вас есть пример другого простого случая, когда try и finally без catch фактически вызывают вызов блока finally?   -  person S Itzik    schedule 30.11.2020