.NET и Исключения C#. Что разумно поймать

Я передал бы ArraySegment в этом случае.

Вы изменили бы Ваш Parse метод к этому:

// Changed TCPHeader to TcpHeader to adhere to public naming conventions.
TcpHeader Parse(ArraySegment buffer)

И затем Вы изменили бы вызов на это:

// Create the array segment.
ArraySegment seg = new ArraySegment(packet, 20, 20);

// Call parse.
TcpHeader header = Parse(seg);

Используя эти ArraySegment не скопирует массив, и он сделает проверку границ Вас в конструкторе (так, чтобы Вы не указывали неправильные границы). Затем Вы изменяете Ваш Parse метод для работы с границами, указанными в сегменте, и необходимо быть в порядке.

можно даже создать перегрузку удобства, которая примет полный массив байтов:

// Accepts full array.
TcpHeader Parse(byte[] buffer)
{
    // Call the overload.
    return Parse(new ArraySegment(buffer));
}

// Changed TCPHeader to TcpHeader to adhere to public naming conventions.
TcpHeader Parse(ArraySegment buffer)

12
задан Community 23 May 2017 в 12:04
поделиться

5 ответов

Мой девиз - обрабатывать то, что вы можете (или нужно), и позволять любым другим исключениям всплывать и перехватывать их в событии UnhandledException.

Вы правы, но блок finally всегда вызывается (даже в случае возникновения исключения в секции try) перед выходом из метода. Так что, хотите ли вы перехватить исключение в методе out или нет, полностью зависит от вас ...

5
ответ дан 2 December 2019 в 05:54
поделиться

По вопросу №2: Автор имел в виду «Исключения поврежденного государства». Они будут представлены в .NET 4.0 (команда CLR объявила об этом на PDC 2008 в в этом докладе).

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

Но вы могли бы перехватить эти исключения:

  1. В main () - записать в журнал, выйти, отключить надстройку
  2. Очень редкие случаи, когда вы знаете, что код генерирует подобное исключение (например, в некоторых случаях с взаимодействием с машинным кодом)

Для этого вы должны поместить атрибут [HandleProcessCorruptedStateException] в метод, где вы хотите перехватить CorruptedStateException.

Чтобы узнать больше об этих исключениях см. эту статью MSDN.

11
ответ дан 2 December 2019 в 05:54
поделиться

Как правило, вы не должны перехватывать исключения, если:

  1. У вас нет особого исключения, которое вы можете обработать и с которым что-то сделаете. Однако в этом случае вы всегда должны проверять, не следует ли вам в первую очередь пытаться учитывать и избегать исключения.

  2. Вы находитесь на верхнем уровне приложения (например, пользовательского интерфейса) и не хотите, чтобы поведение по умолчанию, которое будет представлено пользователю. Например, вам может потребоваться диалоговое окно с сообщением об ошибке в стиле «пришлите нам свои журналы».

  3. Вы повторно генерируете исключение после того, как каким-то образом с ним справитесь, например, если вы откатываете транзакцию БД.

Ваш finally блоки всегда выполняются. Ваш пример кода верен - метод низкого уровня должен иметь только try и наконец . Например, неуправляемый вызов может знать, что ему нужно избавиться от неуправляемого ресурса, но это не будет доступно для вызывающих его методов .Net. Этот вызов должен избавить от неуправляемого ресурса в его блоке finally , а вызов управляемых методов может обрабатывать исключения или просто передавать их.

Если в исключении есть что-то, что вам нужно обработать, вы должны повторно вызовите исключение, например:

try {
    conn.BeginTransaction();
    //do stuff
    conn.CommitTransaction();
}
catch (Exception) {
    conn.RollbackTransaction(); //required action on any exception
    throw; //re-throw, don't wrap a new ex to keep the stack trace
}
finally {
    conn.Dispose(); //always dispose of the resource
}
9
ответ дан 2 December 2019 в 05:54
поделиться

Просто к вашему третьему вопросу:

Если у вас есть

nastyLowLevel() {
  doSomethingWhichMayCorruptSomethingAndThrowsException();
}

MyEvilCatcher() {
  try {
    nastyLowLevel();
  } catch (Exception e) {
    MyExceptionHandler(e);
  }
}

WiseCatcher() {
  try {
    MyEvilCatcher();
  } catch (LowLevelException e) {
    DoSomethingWiseSoFinnalyDontRuinAnything();
  } finally {
    DoSomethingWhichAssumesLowLevelWentOk();
  }
}

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

Как правило, я предпочитаю тщательно продумать, какие исключения могут быть сгенерированы, и явно их перехватить. Я использую «общий обработчик» только на самом внешнем уровне в производственных средах, чтобы регистрировать неожиданные исключения и представлять их заказчику в хорошо отформатированном виде (включая подсказку для отправки нам файла журнала).

1
ответ дан 2 December 2019 в 05:54
поделиться

Я думаю, что приведенный ответ неверен (или, может быть, имелся в виду 2.0 вместо 4.0)? Мне это кажется фальшивкой.

0
ответ дан 2 December 2019 в 05:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: