Возьмите этот код:
using System;
namespace OddThrow
{
class Program
{
static void Main(string[] args)
{
try
{
throw new Exception("Exception!");
}
finally
{
System.Threading.Thread.Sleep(2500);
Console.Error.WriteLine("I'm dying!");
System.Threading.Thread.Sleep(2500);
}
}
}
}
Что дает мне этот результат:
Unhandled Exception: System.Exception: Exception!
at OddThrow.Program.Main(String[] args) in C:\Documents and Settings\username
\My Documents\Visual Studio 2008\Projects\OddThrow\OddThrow\Program.cs:line 14
I'm dying!
Мой вопрос: почему текст необработанного исключения возникает до окончательного? На мой взгляд, наконец, следует исключить, поскольку пакет распаковывается, прежде чем мы даже знаем, что это исключение необработано. Обратите внимание на вызовы Sleep() - они возникают после печати необработанного исключения, как если бы оно выполнялось следующим образом:
- Необработанный текст/сообщение исключений
- Наконец блоки.
- Завершить приложение
В соответствии со стандартом С#, §8.9.5, это неправильное поведение:
- В текущем члене функции рассматривается каждый пример try, который охватывает точку бросания. Для каждого оператора S, начиная с самого внутреннего оператора try и заканчивая внешней инструкцией try, выполняются следующие шаги:
-
- Если блок try из S заключает точку бросания и если S имеет один или несколько кластеров catch, предложения catch рассматриваются в порядке появления, чтобы найти подходящий обработчик для исключения. Первое предложение catch, которое указывает тип исключения или базовый тип типа исключения, считается совпадением. Общее предложение catch (§8.10) считается совпадением для любого типа исключения. Если расположено соответствующее предложение catch, распространение исключения завершается передачей элемента управления блоку этого предложения catch.
-
- В противном случае, если блок try или блок catch из S заключает точку бросания, и если S имеет окончательный блок, управление передается блоку finally. Если блок finally выдает другое исключение, обработка текущего исключения прекращается. В противном случае, когда управление достигает конечной точки блока finally, обработка текущего исключения продолжается.
- Если обработчик исключений не был найден в текущем вызове члена функции, вызов члена функции прекращается. Затем эти шаги повторяются для вызывающего элемента функции с точкой броска, соответствующей оператору, из которого был вызван элемент функции.
- Если обработка исключений завершает все вызовы членов функции в текущем потоке, указывая, что поток не имеет обработчика исключения, то сам поток завершается. Влияние такого завершения определяется реализацией.
Где я ошибаюсь? (У меня есть отдельные сообщения об ошибках консоли, и это в свою очередь. Мало, просто раздражает и заставляет меня подвергать сомнению язык...)