Когда я генерирую исключение HttpRequestException, ожидаемое поведение будет заключаться в том, чтобы войти в перехват указанной ошибки c, а затем в перехват без параметра.
Ваше ожидание полностью противоречит реальность; Мне интересно знать, как люди приходят к таким ложным убеждениям о языках программирования, поэтому, если у вас есть минутка, чтобы оставить комментарий, объясняющий, как вы пришли к этому ложному убеждению, я был бы признателен.
Точная природа того, как ваши убеждения ошибочны, не очень ясна. Похоже, вы верите в одну из двух ложных вещей: либо (1) выполняется каждый соответствующий блок catch, а не только первый, или (2) повторный бросок в блоке catch, который находится вне try block вызывает выполнение другого блока catch "down down".
Документированное и разработанное поведение C# в отношении обработки исключений состоит в том, что процесс обработки исключений происходит следующим образом:
- Исключение выдается
- среда выполнения анализирует стек, чтобы найти вмещающие блоки try с предложениями catch.
- Кадры стека перечисляются в порядке от самого последнего к наименее последнему.
- Кадр стека может быть связан с вызовом, который имеет несколько окружающие блоки try с предложениями catch вокруг сайта вызова. В этом случае блоки try также проверяются в порядке от самого внутреннего к внешнему.
- Для каждого включающего в себя блока try с предложением catch элементы catch catch проверяются в программном порядке сверху вниз.
- Неохраняемое предложение catch соответствует всем. Предложение catch с типом соответствует исключению этого типа. Предложение catch с фильтром выполняет фильтр. Обратите внимание, что фильтры выполняются перед окончательной блокировкой .
- Как только определенное совпадение с first определено, поиск останавливается.
OK Таким образом, в этот момент произошла одна из двух вещей. Либо мы определили блок catch, связанный с этим исключением, либо такого блока catch нет. Если такого блока нет, то поведение программы становится неопределенным . В этот момент среда выполнения может решить сделать несколько вещей, включая запуск отладчиков, запуск или отсутствие запуска блоков finally, запуск или отсутствие запуска обработчиков событий «необработанное исключение» и т. Д. Обратитесь к документации времени выполнения для деталей; это не охватывается спецификацией C#.
Если есть блок catch, тогда мы начинаем выполнять заключающие блоки finally; если они все выполняются до завершения нормально, тогда мы выполняем идентифицированный соответствующий блок catch, и вот и все . Больше блоки захвата не выполняются. (Если блоки finally завершаются с исключением, тогда весь процесс начинается снова с поиска совпадающего улова.)
Представление о том, что каждый соответствующий совпадающий блок catch будет выполняться, просто ложно, поэтому остановите веря в это. И представление о том, что бросок в блоке захвата каким-то образом пойман, как если бы он был брошен изнутри try
, также неверно, так что не верьте этому.
Если вы хотите, чтобы блок «перехватить все» выполнялся всегда, используйте следующую структуру:
try
{
try
{
do the stuff
}
catch (your type) when your filter
{
do more stuff
throw; // re-throw to execute the outer "Pokemon" block.
}
}
catch
{
now this always runs on exception
}
Имеет ли это смысл?