Избегание сообщений об исключении первого шанса, когда исключение безопасно обработано
Вопрос
Следующий фрагмент кода перехватывает исключение EOS.
using (var reader = new BinaryReader(httpRequestBodyStream)) {
try {
while (true) {
bodyByteList.Add(reader.ReadByte());
}
} catch (EndOfStreamException) { }
}
Так почему же я все еще получаю исключения первого шанса на своей консоли?
В mscorlib.dll произошло первое случайное исключение типа System.IO.EndOfStreamException.
Есть ли способ скрыть эти сообщения об исключении первого шанса?
Решение
Смысл исключений «первого шанса» заключается в том, что вы видите их предварительный обработчик, чтобы вы могли остановиться на них во время отладки в момент выдачи.Исключением «второго шанса» является исключение, не имеющее соответствующего обработчика.Иногда вам нужно перехватить исключения «первого шанса», потому что важно увидеть, что происходит, когда оно генерируется, даже если кто-то его перехватывает.
Не о чем беспокоиться.Это нормальное поведение.
Другие советы
Чтобы не видеть сообщения, щелкните правой кнопкой мыши окно вывода и снимите флажок «Сообщения об исключениях».
Однако было бы неплохо увидеть, как они происходят, если вы хотите знать, когда возникают исключения, без установки точек останова и перенастройки отладчика.
1) В Visual Studio вы можете изменить настройки способа обработки (прерывания) исключений отладчиком.
Перейдите в раздел «Отладка» > «Исключения».(Обратите внимание, что этого может не быть в вашем меню, в зависимости от настроек среды Visual Studio.Если нет, просто добавьте его в свое меню с помощью меню «Настроить».)
Там вам представлен диалог исключений и того, когда на них следует прерываться.
В строке «Исключения общего языка во время выполнения» вы можете снять флажок «Выбрасывать» (который тогда перестанет беспокоить вас по поводу исключений первого шанса), а также вы можете отменить выбор «Необработанные пользователем» (что я бы не рекомендовал), если хотите.
2) Получаемое вами сообщение не должно отображаться в консоли, но должно появляться в окне «Вывод» Visual Studio.Если последнее так, то я не нашел возможности удалить это, но оно не появляется, если вы запускаете приложение без Visual Studio.
Надеюсь, это поможет.
В отличие от Java, исключения .NET довольно затратны с точки зрения вычислительной мощности, и обрабатываемых исключений следует избегать при нормальном и успешном пути выполнения.
Вы не только избежите беспорядка в окне консоли, но и улучшите свою производительность, а счетчики производительности, такие как исключения .NET CLR, станут более информативными.
В этом примере вы бы использовали
while (reader.PeekChar() != -1)
{
bodyByteList.Add(reader.ReadByte());
}
У меня была эта проблема, и я не мог понять, где было выбрано исключение.Поэтому мое решение заключалось в том, чтобы позволить Visual Studio прекратить выполнение такого исключения.
- Перейдите к «Отладка/Исключения».
- Разверните дерево «Исключения среды общего языка».
- Разверните ветку «Система».
- Прокрутите вниз до того места, где находится «NullReferenceException», и проверьте флажок «бросить», и снимите «Handled User-Handled».
- Отладка вашего проекта.
Если вам нужен больший контроль над этими сообщениями, вы можете добавить обработчик:
Friend Sub AddTheHandler()
AddHandler AppDomain.CurrentDomain.FirstChanceException, AddressOf FirstChanceExceptionHandler
End Sub
<Conditional("DEBUG")>
Friend Sub FirstChanceExceptionHandler( source As Object, e As Runtime.ExceptionServices.FirstChanceExceptionEventArgs)
' Process first chance exception
End Sub
Это позволяет вам заставить их замолчать, как упоминалось в других комментариях, но при этом гарантирует, что вы сможете о них знать.Я считаю, что приятно видеть, сколько я действительно выбрасываю, если записываю сообщение и метку времени в текстовый файл.
На самом деле, если у вас много исключений в секунду, вы должны добиться большей производительности, проверив значение read.EndOfStream..Распечатка этих сообщений об исключениях происходит невероятно медленно, и их сокрытие в Visual Studio ничего не ускорит.
в ВБ.НЕТ:
<DebuggerHidden()> _
Public Function Write(ByVal Text As String) As Boolean
...
Я думаю, что поток выдает это исключение, поэтому ваша попытка ограничена, чтобы его перехватить.
Добавьте еще несколько комбинаций try catch в разных областях, пока не поймаете их там, где они на самом деле выбрасываются, но, похоже, это происходит либо за пределами вашего использования, поскольку объект потока не создается в области использования.