Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
 Аватар для Robesper3411
20 / 19 / 3
Регистрация: 20.02.2012
Сообщений: 535
Записей в блоге: 1

Не выполняется finally в try-finally

30.05.2024, 08:46. Показов 1659. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем доброго времени суток!
Запускаю отладку для кода:
C#
1
2
3
4
5
6
7
8
9
10
try
{
    int a = 10;
    int b = 0;
    int c = a / b;
}
finally
{
    Console.WriteLine("Finally");
}
Получаю вывод:
Unhandled exception. System.DivideByZeroException: Attempted to divide by zero.
at Program.<Main>$(String[] args) in D:\Sandbox\Program.cs:line 5
В блок finally не попадем. Что с данным кодом не так? Вроде как finally должен выполняться всегда. Или я чего-то не учитываю?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
30.05.2024, 08:46
Ответы с готовыми решениями:

Всегда ли выполняется блок finally
A) Нет, если в блоке try выполнен оператор return B) Нет, если в блоке catch выполнен оператор return C) Да D) Нет, если в блоке...

Catch и finally
Доброго времени суток. Подскажите, пожалуйста, как правильно прописывать исключения(и в чем разница между try-catch-finally,try-catch и...

try.catch.finally в калькуляторе
Подскажите пожалуйста, где нужно вставить блок try...catch..finally в калькуляторе. using System; using System.Collections.Generic; ...

22
Эксперт .NET
 Аватар для Usaga
14084 / 9302 / 1347
Регистрация: 21.01.2016
Сообщений: 34,908
30.05.2024, 08:57
Robesper3411, у тебя исключение не перехватывается и потому приложение валится. Соответственно, до finally уже дело не доходит.
0
 Аватар для Robesper3411
20 / 19 / 3
Регистрация: 20.02.2012
Сообщений: 535
Записей в блоге: 1
30.05.2024, 09:12  [ТС]
Usaga, погоди... Но finally же выполняется, даже если блок catch отсутствует.
Или я чего-то не понимаю в конструкции try-catch-finally?!
0
 Аватар для Andrey-MSK
3308 / 2196 / 386
Регистрация: 14.08.2018
Сообщений: 7,392
Записей в блоге: 4
30.05.2024, 09:29
Цитата Сообщение от Robesper3411 Посмотреть сообщение
Но finally же выполняется, даже если блок catch отсутствует.
finally выполнится в любом случае - либо в try, либо в catch. А у вас блока catch нет, что он делать будет с упавшим приложением? Сделайте catch, выведите ошибку и после выведется то что в finally.
0
Эксперт .NET
 Аватар для Rius
13025 / 7590 / 1661
Регистрация: 25.05.2015
Сообщений: 23,088
Записей в блоге: 14
30.05.2024, 09:38
Robesper3411,
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
try
{
  try
  {
      int a = 10;
      int b = 0;
      int c = a / b;
  }
  finally
  {
      Console.WriteLine("Finally");
  }
}
catch
{}
1
 Аватар для Andrey-MSK
3308 / 2196 / 386
Регистрация: 14.08.2018
Сообщений: 7,392
Записей в блоге: 4
30.05.2024, 09:42
Rius, О как
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,226
30.05.2024, 09:46
Robesper3411, чтобы блок finally выполнил код, процесс должен продолжить выполнение.
А у вас он просто крашится из-за UnhandledException, именно поэтому хоть где-то исключение должно быть перехвачено.

Добавлено через 3 минуты
Вот другой пример:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Task.Run(() =>
{
    using var a = new A();
    a.Foo();
});
Console.WriteLine("Press enter to exit");
Console.ReadLine();
 
 
class A : IDisposable
{
    public bool Disposed { get; private set; }
 
    public void Dispose()
    {
        Disposed = true;
        Console.WriteLine("I have been disposed");
    }
 
    public void Foo()
    {
        throw new Exception("Unexpected!");
        Console.WriteLine("Foo!");
    }
}
Процесс продолжает выполнение, а исключение вообще теряется. Но блок finally отрабатывает (в который using конвертируется).
1
 Аватар для Robesper3411
20 / 19 / 3
Регистрация: 20.02.2012
Сообщений: 535
Записей в блоге: 1
30.05.2024, 10:06  [ТС]
Rius, то есть если выше по стеку не будет нигде блока catch, то краш приложения?
0
Эксперт .NET
 Аватар для Rius
13025 / 7590 / 1661
Регистрация: 25.05.2015
Сообщений: 23,088
Записей в блоге: 14
30.05.2024, 10:10
Лучший ответ Сообщение было отмечено Robesper3411 как решение

Решение

https://learn.microsoft.com/en... statements

When an exception is thrown, the common language runtime (CLR) looks for the catch block that can handle this exception. If the currently executed method doesn't contain such a catch block, the CLR looks at the method that called the current method, and so on up the call stack. If no catch block is found, the CLR terminates the executing thread. For more information, see the How exceptions are handled section of the C# language specification.
In almost all cases finally blocks are executed. The only cases where finally blocks aren't executed involve immediate termination of a program. For example, such a termination might happen because of the Environment.FailFast call or an OverflowException or InvalidProgramException exception. Most operating systems perform a reasonable resource clean-up as part of stopping and unloading the process.
2
 Аватар для Robesper3411
20 / 19 / 3
Регистрация: 20.02.2012
Сообщений: 535
Записей в блоге: 1
30.05.2024, 10:13  [ТС]
IamRain, Ваш пример показался мне интересным. Непонятно только, почему выполняется finally? У тасков есть свои механизмы для отлова исключений?
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,226
30.05.2024, 10:23
Лучший ответ Сообщение было отмечено Robesper3411 как решение

Решение

Цитата Сообщение от Robesper3411 Посмотреть сообщение
У тасков есть свои механизмы для отлова исключений?
Да, таски умеют в это. Точный механизм, почему выполняется finally, я не знаю (не читал спеку).

Если таску заменить на ThreadPool.QueueUserWorkItem, процесс тоже крашнется.
1
 Аватар для Robesper3411
20 / 19 / 3
Регистрация: 20.02.2012
Сообщений: 535
Записей в блоге: 1
30.05.2024, 10:38  [ТС]
IamRain, спасибо большое за ответ. Вам бы тоже дал "Лучший ответ", но можно всего для одного ответа тыкнуть.
0
 Аватар для Andrey-MSK
3308 / 2196 / 386
Регистрация: 14.08.2018
Сообщений: 7,392
Записей в блоге: 4
30.05.2024, 10:39
Цитата Сообщение от Robesper3411 Посмотреть сообщение
но можно всего для одного ответа тыкнуть.
Три можно
0
Эксперт .NET
 Аватар для Rius
13025 / 7590 / 1661
Регистрация: 25.05.2015
Сообщений: 23,088
Записей в блоге: 14
30.05.2024, 10:48
Лучший ответ Сообщение было отмечено Robesper3411 как решение

Решение

Robesper3411, ознакомьтесь ещё с Исключения среди исключений в .NET
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,226
30.05.2024, 10:57
Если читать спеку из документации, то там можно найти вот такой фрагмент:
If no matching catch clause is found:
...
Otherwise, if the search for matching catch clauses reaches the code that initially started the thread, then execution of the thread is terminated. The impact of such termination is implementation-defined.
Идет поиск try/catch блока вверх по стеку, если будет найден таковой, то будет передано управление ему, если не было найдено finally блоков. Если они были найдены, то сначала выполняться они, а потом уже catch блок.

Если был найден catch и рядом с ним в том же стекфрейме (это уже на практике проверил, в спеке не увидел), то сначала выполняется catch блок, потом уже finally блок.

Если ничего не найдено, то просто завершается поток, а как это повлияет на весь процесс - деталь реализации (подсвечено в цитате).
Лично я ожидал из кода ниже, что при появлении исключения процесс продолжит выполнение, но он крашнулся со 134 (Linux runtime).
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var t = new Thread(_ =>
{
    using var a = new A();
    a.Foo();
}) { IsBackground = true };
Console.WriteLine("Press enter to exit");
t.Start();
Console.ReadLine();
 
 
class A : IDisposable
{
    public bool Disposed { get; private set; }
 
    public void Dispose()
    {
        Disposed = true;
        Console.WriteLine("I have been disposed");
    }
 
    public void Foo()
    {
        throw new Exception("Unexpected!");
        Console.WriteLine("Foo!");
    }
}
Добавлено через 2 минуты
Есть еще продвинутые вещи (далеко не всем надо), на .DOTNEXT-е были доклады - у Жени Пешкова и Адама Ситника.
1. https://www.youtube.com/watch?v=U92Ts53win4
2. https://www.youtube.com/watch?v=WLSrYgMWif4

Добавлено через 2 минуты
Цитата Сообщение от IamRain Посмотреть сообщение
но он крашнулся со 134 (Linux runtime).
Под Windows тоже надо бы отдельно проверять.
1
151 / 135 / 29
Регистрация: 02.07.2013
Сообщений: 962
30.05.2024, 13:03
Цитата Сообщение от IamRain Посмотреть сообщение
Robesper3411, чтобы блок finally выполнил код, процесс должен продолжить выполнение.
у меня вообще другая картина мира.
finaly всегда выполнится, даже если процесс завершит свою работу. иначе как вернутся неуправляемые ресурсы в систему при использовании Using?

приложение сначала ищет ближайший по стеку catch. если не находит, то падает, а затем выполняет все finaly по стеку вызовов. если в finaly conlose.Writeline, вот для завершенного приложения этот метод, вероятно, не работает. оно и не удивительно. приложение завершено.

а почему в консоль ничего не пишет? - так может и пишет в буфер какой-нибудь, но на печать уже не отправляет так как поток, который управляет окошком консоли уже отклеился от упавшего приложения.
может, конечно я неправ, поправьте меня.
0
Эксперт .NET
 Аватар для Rius
13025 / 7590 / 1661
Регистрация: 25.05.2015
Сообщений: 23,088
Записей в блоге: 14
30.05.2024, 13:06
finaly всегда выполнится, даже если процесс завершит свою работу. иначе как вернутся неуправляемые ресурсы в систему при использовании Using?
Не всегда. Возвратом займётся операционная система.
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,226
30.05.2024, 13:20
golosalex, вы прочитали цитаты из документаций, приведенных двумя разными людьми тут?
Post 9:
In almost all cases finally blocks are executed. The only cases where finally blocks aren't executed involve immediate termination of a program. For example, such a termination might happen because of the Environment.FailFast call or an OverflowException or InvalidProgramException exception. Most operating systems perform a reasonable resource clean-up as part of stopping and unloading the process.
Цитата Сообщение от IamRain Посмотреть сообщение
Robesper3411, чтобы блок finally выполнил код, процесс должен продолжить выполнение.
Здесь отвечал интуитивно, и интуиция не подвела.

Дальше выдержки из спеки, Post 15:
Otherwise, if the search for matching catch clauses reaches the code that initially started the thread, then execution of the thread is terminated.
Видите, картинка складывается, есть непротиворечащие друг другу цитаты из документации, finally выполняется НЕ всегда.
В конце концов, вы код то запускали?
0
151 / 135 / 29
Регистрация: 02.07.2013
Сообщений: 962
30.05.2024, 13:23
Цитата Сообщение от Rius Посмотреть сообщение
Не всегда. Возвратом займётся операционная система.
хм... думал вам показать пример с мутексами, а оказывается и правда все выглядит так как будто винда освобождает рессурсы, потому, что после падения приложения которое мутекс создало первым. приложение, которое этот мутекс ждало тоже упало)))
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,226
30.05.2024, 13:37
Цитата Сообщение от golosalex Посмотреть сообщение
иначе как вернутся неуправляемые ресурсы в систему при использовании Using?
Также упоминается из поста 9:
Цитата Сообщение от Rius Посмотреть сообщение
Most operating systems perform a reasonable resource clean-up as part of stopping and unloading the process.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.05.2024, 13:37
Помогаю со студенческими работами здесь

Блоки try , catch и finally
Доброго времени суток бойцы , решил поделится с вами одним наблюдением , может кто-то добавит еще что-то по этой теме.... Всем...

Поясните конструкцию try/catch/finally
try { } catch { } finally {

Очередность обработки в try-catch-when-finally
есть код static void Main(string args) { try { Method(); ...

Правильное использование try catch finally
Добрый день подскажите как правильно записать следующий код который записывает в файл натуральные числа от 1 до n static void...

Проверка наличия Exception в блоке finally
Всем привет! Как в блоке finally {} проверить срабатывали ли Exception в блоках catch {} ? Спасибо!


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru