Лучшая альтернатива Try Catch madness?

Есть ли лучшая альтернатива попытке поймать безумие в приведенном ниже коде? Я собираю всевозможную подобную системную информацию, и у меня есть еще несколько этих надоедливых конструкций try catch, и я очень хотел бы избавиться от них.

Обратите внимание, что это действительно имеет смысл. Не вся информация о процессе в блоках try может быть получена, а то, что недоступно, в любом случае является необязательным, в то же время недопустимо пропускать то, что доступно, поэтому не существует только одной пары try catch.

Если бы только эти операторы try catch могли войти в метод Append().

foreach (Process proc in Process.GetProcesses())
{
    try { Append(proc.Threads.Count); } catch { }
    try { Append(proc.Id); } catch { }
    try { Append(proc.ProcessName); } catch { }
    try { Append(proc.BasePriority); } catch { }
    try { Append(proc.StartTime); } catch { }

    Append(proc.HandleCount,
        proc.PrivateMemorySize64,
        proc.NonpagedSystemMemorySize64,
        proc.PagedMemorySize64,
        proc.PeakPagedMemorySize64,
        proc.PeakVirtualMemorySize64);
}

Вы можете добавить метод SafeAppend<T>(Func<T> getter), который выполняет try { Append(getter()); } catch { }, а затем использовать его в исходном коде: SafeAppend(() => proc.Threads.Count);

Martin Costello 04.07.2019 16:12

Однако сколько из этих строк может выйти из строя фактически? В моих тестах только StartTime мог привести к отказу в доступе. Другая информация представляется общедоступной независимо от того, есть ли у вас доступ к процессу или нет. (Предполагается, что Process — хорошо известный класс System.Diagnostics.Process.)

Jeroen Mostert 04.07.2019 16:15

@ V0ldek Довольно сложно изменить встроенные в .NET классы или свойства, которые могут создавать ошибки.

Sami Kuhmonen 04.07.2019 16:15

Слово предупреждения, если это будет вызываться довольно часто и потенциально будет перехватывать множество исключений, это может стать серьезным ударом по производительности. Исключения довольно дороги, поэтому их следует избегать, если это вообще возможно.

DavidG 04.07.2019 16:17

@Denis Schaf - Почему это плохо?

Thorham 04.07.2019 16:18

Что заставляет вас думать, что если, например, proc.Id не удалось получить идентификатор процесса, вы могли бы получить имя процесса, базовый приоритет и т. д.? Другими словами: почему бы просто не использовать один try-catch для всех добавлений?

user2819245 04.07.2019 16:18

И, пожалуйста, ловите соответствующие исключения. Вы не хотите, чтобы NullReferenceException остался незамеченным.

Patrick Hofman 04.07.2019 16:20

@Jeroen Mostert - зависит от ОС. В моей программе их больше, и некоторые из них (информация о диске) не работают под Linux, но не под Windows.

Thorham 04.07.2019 16:20

@DavidG - вызывается только один раз за выполнение программы.

Thorham 04.07.2019 16:21

Вы не делаете ничего плохого, и ваш код безопасен, вы защищены, и эти функции могут вызывать исключения. Подход @MartinCostello выглядит элегантно, я бы проголосовал за это.

Miguel Mateo 04.07.2019 16:22

@elgonzo - я не знаю, и мне все равно, потому что я хочу надежный способ сделать это для всех случаев, которые мне нужны, и мне больше не нужно об этом думать. Возможно, это не очень хорошая идея.

Thorham 04.07.2019 16:22

Ну, вы могли бы просто использовать один try-catch, окружающий все ваши Appends. Что тогда было бы менее надежным?

user2819245 04.07.2019 16:24

elgonzo - Да, я это знаю (см. исходный вопрос), но я хочу убедиться, что ничего не пропущу.

Thorham 04.07.2019 16:25

Другой вариант — использовать директивы компилятора для выполнения только тех команд, которые, как вы знаете, будут работать на каждой платформе. См. здесь или здесь, как это сделать. Теперь вы просто обертываете все это одной попыткой/поймать.

DavidG 04.07.2019 16:29

@DavidG - И тогда мне нужно будет понять, что с чем работает. Гораздо проще, если у меня есть только один метод Append(), который всегда работает без сбоев.

Thorham 04.07.2019 16:31

@Martin Costello - кажется, ваши предложения работают, спасибо!

Thorham 04.07.2019 16:31

Да, лично я бы предпочел знать, что работает на каждой платформе...

DavidG 04.07.2019 16:31

@DavidG - это просто не вариант, потому что некоторые из этих перехватов попыток просто не работают в Linux, в то время как платформа поддерживает эти функции. Документация Microsoft, похоже, не содержит никакой информации об этом. Кроме того, существует проблема количества платформ и версий платформ. Огромная боль, которой можно полностью избежать одним методом благодаря Мартину Костелло.

Thorham 04.07.2019 16:35

Нет, версии платформы не будут иметь никакой разницы, он либо работает на платформе, либо нет. Ваш подход — это молоток для чего-то, что требует большей утонченности. Как вы видите в ответе Патрика, просто протестируйте каждую платформу, и если документы неверны/отсутствуют, обновите их — все они доступны для редактирования на Github.

DavidG 04.07.2019 16:38

@ DavidG - Но что я от этого получу, кроме дополнительного кода? Иногда чем проще, тем лучше.

Thorham 04.07.2019 16:41

Молча поедать исключения — это зло.

3Dave 04.07.2019 16:43

@ 3Dave - Не в этом случае. То, что недоступно, является необязательным. Информация, которую я собираю, хэшируется с помощью Sha256 для создания начального числа для некриптографического генератора случайных чисел, который не зависит от системного криптографического генератора случайных чисел. Таким образом, в этом случае информация, которую нельзя получить, действительно является необязательной, поэтому она не имеет значения. Это немного нишевый случай.

Thorham 04.07.2019 16:45
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
22
138
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

На мой взгляд, ваш подход в целом неверен, но он будет работать. Вы можете «оптимизировать» это в удобочитаемости, используя метод:

private void AppendSafe<T>(Func<T> f)
{
    T val;

    try
    {
        val = f();
    }
    catch { return; }

    Append(val);
}

AppendSafe(() => proc.Threads.Count);
AppendSafe(() => proc.Id);
AppendSafe(() => proc.ProcessName);
AppendSafe(() => proc.BasePriority);
AppendSafe(() => proc.StartTime);

Но я бы сказал, чтобы поймать соответствующие исключения. Вы не хотите, чтобы NullReferenceException остался незамеченным.

Кроме того, поскольку исключения обходятся дорого, лучше выяснить, какие свойства доступны на каких платформах, и протестировать их. По крайней мере, вы минимизируете влияние на производительность при частом вызове этого.

Все исключения перехвачены в моем коде, я специально проверил каждое свойство на предмет этого. Код запускается только один раз за выполнение программы, так что это абсолютно не проблема.

Thorham 04.07.2019 16:37

В этом случае вы учитываете все журналы и т. д., Исключения первого шанса и т. д., Но в целом это хорошо.

Patrick Hofman 04.07.2019 16:51

Исключения могут быть проблемой в масштабе (может быть, экстремальный пример, но у Троя Ханта был свой проблемы с ними). Я думаю, что наша общая цель состоит в том, чтобы попытаться избежать их, если вы можете. Этот ответ отличный, но я бы предпочел понять для каждой платформы, что должно и не должно работать.

DavidG 04.07.2019 16:55

@DavidG Как я и предполагал («лучше выяснить, какие свойства доступны на каких платформах, и проверить это»).

Patrick Hofman 04.07.2019 16:56

Это нишевый случай. Информация собирается только для заполнения большого состояния некриптографического PRNG. Что доступно, а что нет на какой платформе, кажется не столь важным. Возможно, мне следовало уточнить это в исходном вопросе.

Thorham 04.07.2019 17:26

Другие вопросы по теме