Уникнення повідомлень про перші випадкові випадки, коли безпека обробляється безпечно


77

Наступний біт коду виявляє виняток EOS

using (var reader = new BinaryReader(httpRequestBodyStream)) {

    try {
        while (true) {
            bodyByteList.Add(reader.ReadByte());
        }
    } catch (EndOfStreamException) { }
}

То чому я все ще отримую винятки першої можливості у своїй консолі?

Перший випадковий виняток типу 'System.IO.EndOfStreamException' стався в mscorlib.dll

Чи є спосіб приховати ці перші шанси на виняток?

Відповіді:


79

Суть винятків "перший шанс" полягає в тому, що ви бачите їх попереднім обробником, щоб ви могли зупинитися на них під час налагодження в момент кидання. Виняток "другий шанс" - це виняток, який не має відповідного обробника. Іноді хочеться вловити винятки "перший шанс", тому що важливо бачити, що відбувається, коли його кидають, навіть якщо хтось це ловить.

Немає чим займатися. Це нормальна поведінка.


58
Справді, це ні до чого, але вони справді захаращують журнал виведення налагодження :(
Димитрі С.

190

Щоб уникнути перегляду повідомлень, клацніть правою кнопкою миші на вікні виводу та зніміть прапорець біля пункту "Повідомлення про винятки".

Однак побачити, як вони трапляються, може бути приємно, якщо вам цікаво знати, коли виникають винятки, не встановлюючи точки зупинки та не переналаштовуючи налагоджувач.


19

1) У Visual Studio ви можете змінити параметри способу обробки (відключення) винятків налагоджувачем.

Перейдіть до Налагодження> Винятки. (Зауважте, цього може не бути у вашому меню, залежно від налаштувань середовища Visual Studio. Якщо не просто додати його до свого меню за допомогою меню Налаштувати.)

Там вам буде представлено діалогове вікно винятків і час, коли на них слід зупинитися.

У рядку "Виключення загальної мови під час виконання" ви можете скасувати вибір викинутого (що в подальшому має перестати турбувати вас щодо винятків, що мають першу можливість), а також можете скасувати вибір непідготовленого користувача (що я б не рекомендував), якщо захочете.

2) Повідомлення, яке ви отримуєте, не повинно знаходитись у консолі, але повинно з’являтися у вікні „Вивід” Visual Studio. Якщо це останнє, то я не знайшов можливості видалити це, але воно не з’являється, якщо ви запускаєте програму без Visual Studio.

Сподіваюся, що це допомагає.


11

На відміну від Java, винятки .NET є досить дорогими з точки зору обчислювальної потужності, і оброблених винятків слід уникати у звичайному та успішному шляху виконання.

Ви не тільки уникнете метушні у вікні консолі, але і ваша продуктивність покращиться, і це зробить лічильники продуктивності, такі як винятки .NET CLR, більш значимими.

У цьому прикладі ви б використали

while (reader.PeekChar() != -1)
{
    bodyByteList.Add(reader.ReadByte());
}

1
або ви можете отримати всі байти одним кадром за допомогою ReadBytes, а також скористатися буферизацією. але, мабуть, не в цьому було питання.
Крейг Тайлер

9
Звичайно, це так. "Чи є спосіб приховати ці перші випадкові повідомлення про виключення?" - перші випадкові винятки не з'являться з цим циклом. :)
loudej

7

У мене була ця проблема, і я не міг зрозуміти, куди було кинуто виняток. Отже, моє рішення було дозволити Visual Studio зупинити виконання такого роду винятків.

  1. Перейдіть до пункту "Налагодження / Винятки"
  2. Розгорніть дерево "Винятки загальної мови під час виконання".
  3. Розгорніть гілку "Система".
  4. Прокрутіть униз до місця, де знаходиться "NullReferenceException", і встановіть прапорець "кидати", і зніміть прапорець "обробляється користувачем".
  5. Налагодьте свій проект.

4

Якщо ви хочете отримати більше контролю над цими повідомленнями, ви можете додати обробник:

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

Це дозволяє вам замовчувати їх, як згадувалося в інших коментарях, але все одно гарантує, що ви зможете про них знати. Я вважаю, що добре бачити, скільки я насправді кидаю, якщо реєструю повідомлення та позначку часу у текстовому файлі.


1
Гарна пропозиція. Але варто зазначити, що System.Runtime.ExceptionServices доступний лише у .Net 4.0 або новішої версії. Для тих, хто має справу зі застарілим кодом, написаним на .Net 3.5 (або старшій версії).
paulsm4

Дійсний для ASP.NET ?
Кікенет

2

Насправді, якщо у вас багато винятків за секунду, ви б досягли кращої продуктивності, перевіривши значення read.EndOfStream. Друк цих повідомлень про винятки неймовірно повільний, і приховування їх у візуальній студії нічого не прискорить.


-1

у VB.NET:

<DebuggerHidden()> _
Public Function Write(ByVal Text As String) As Boolean
   ...

1
Це не має нічого спільного з цим питанням.
Джон Сондерс,

Насправді, використання [DebuggerNonUserCode] дійсно приховує повідомлення "виняток першої можливості". Я не здивуюсь, DebuggerHidden також робить це.
Рубен

Я не впевнений, чи вважаються вони винятками, але [DebuggerNonUserCode] не приховає жодного з "Керованих помічників налагодження". Наприклад, я отримую BindingFailures, коли використовую XmlSerializer, і я ще не знайшов способу приховати його, крім зняття прапорця BindingFailure при киданні з діалогового вікна "Винятки".
Ентоні Бріен,

Здається, що використання DebuggerHiddenAttributeпросто означає, що перший виняток шансу буде показано на виклику методу, а не самого методу.
Торарін,

-4

Я думаю, що потік кидає цей виняток, тому ваша спроба обмежується, щоб звузити його.

Додайте ще декілька комбінованих спробувловлювання навколо різних областей, поки ви не вловите його там, де він насправді кинутий, але, здається, це відбувається або поза нашою стороною, де ви використовуєте, оскільки об’єкт потоку не створюється в області використання.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.