В чем существенная разница между двумя методами HandleException() блока приложений обработки исключений (Ent Lib 4.1)

В самой последней версии (4.1, выпущенной в октябре 2008 г.) блока приложений для обработки исключений в Microsoft Enterprise Library есть две сигнатуры метода HandleException(), и я немного не понимаю их назначения, тем более что ни документация, ни intellisense , ни приложения QuickStart не имеют существенной разницы.

Вот две подписи:

bool HandleException(Exception exceptionToHandle, string policyName);

bool HandleException(Exception exceptionToHandle, string policyName, out Exception exceptionToThrow);

Все примеры, которые я нашел, используют первый, как в этом примере прямо из комментариев XML-документации к фактическому методу:

try
{
   Foo();
}
catch (Exception e)
{
   if (ExceptionPolicy.HandleException(e, name)) throw;
}

А вот из того же источника (комментарии XML-документа к методу) пример использования второго:

try
{
   Foo();
}
catch (Exception e)
{
   Exception exceptionToThrow;
   if (ExceptionPolicy.HandleException(e, name, out exceptionToThrow))
   {
      if(exceptionToThrow == null)
         throw;
      else
         throw exceptionToThrow;
   }
}

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

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


person Jason Bunting    schedule 13.02.2009    source источник


Ответы (3)


Если вы используете обработчик замены в конфигурации корпоративной библиотеки, ваше исключение замены возвращается с помощью второй подписи .. , out Exception exceptionToThrow).

person Paul Berry    schedule 03.06.2009
comment
Я собираюсь принять ваш ответ, чтобы закрыть это, так как, похоже, никто не заботится об этом, кроме меня! Для данного примера я не вижу, какое значение добавляет второй - если вы настроили конфигурацию для переноса/замены исходного исключения, внутри оно может просто заменить переданное (поскольку оно передается по ссылке), поскольку все исключения полиморфны с System.Exception, и это все, что нужно сделать. Я могу придумать несколько случаев, когда, возможно, вы захотите сохранить оригинал, но это было бы достаточно легко сделать с переменной temp, если это действительно необходимо. - person Jason Bunting; 03.06.2009
comment
Кстати, я дал вам +1, так как вы ответили на вопрос, и ваш ответ действителен. Моя претензия в основном в том, что я не вижу необходимости в перегрузке. - person Jason Bunting; 03.06.2009
comment
@JasonBunting Вы путаете ссылочный тип с передачей по ссылке. Это ссылочный тип (Exception), передаваемый по значению (поскольку ключевое слово ref отсутствует). Другими словами, создается копия ссылки, и манипулирование этой копией ничего не даст. Это правда, что в противном случае вы могли бы изменить объект, на который ссылаются, и это, очевидно, было бы видно коду, содержащему другую ссылку на тот же объект. Но если вы измените копию ссылки так, чтобы она ссылалась на другой объект... ну, внешне это никак не повлияет. - person The Dag; 08.08.2012

Основное различие между двумя перегрузками метода заключается в том, что

bool HandleException(Exception exceptionToHandle, string policyName);

вызовет исключение, если для PostHandlingAction установлено значение ThrowNewException.


В то время как перегрузка второго метода:

bool HandleException(Exception exceptionToHandle, string policyName, out Exception exceptionToThrow);

в этом случае не генерирует исключение, а вместо этого возвращает исключение для повторного создания в качестве выходного параметра.

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

Таким образом, вторая перегрузка дает вам немного больше контроля, поскольку вы можете выполнить некоторую дополнительную логику перед броском. Он также стандартизирует API в том смысле, что если вы используете второй метод HandleException с параметром out, Enterprise Library никогда не будет намеренно обрабатывать ваше исключение и выдавать его за вас. то есть первый метод иногда выбрасывает, а иногда полагается на то, что вы повторно выдаете (в случае NotifyRethrow), но второй метод всегда возвращает и позволяет вызывающей стороне выбрасывать/перебрасывать.

person Randy supports Monica    schedule 18.11.2009

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

            try
            {
                throw new InvalidCastException();
            }
            catch (InvalidCastException ex)
            {
                Exception ex1;
                bool rethrow = ExceptionPolicy.HandleException(ex, "ReplacePolicy1", out ex1);

                if (rethrow)
                {
                    throw new FaultException<ApplicationException>((ApplicationException)ex1, ex1.Message);
                }
            }

Создание FaultException (с контрактом Fault, настроенным для операции WCF) не позволяет службе WCF сообщать об ошибке в вызывающем приложении/службе.

Без второй подписи я бы боролся с упрощением/распространением ошибок через границы службы WCF.

Спасибо, Пол. (мод к коду 07.08.09 - исправление комментария от Джона, спасибо)

person Paul Berry    schedule 08.07.2009
comment
Павел, вы используете его неправильно. Во-первых, вам не нужно использовать ex1 = new Exception(), поскольку вы собираетесь перезаписать его. Далее, rethrow==true означает генерировать то, что HandleException передает вам в ex1, а не генерировать ваше собственное. Если вы хотите генерировать FaultException‹ApplicationException›, вы должны настроить его. - person John Saunders; 08.07.2009
comment
Джон, это должно быть (Исключение ex1;) да. Ваше второе утверждение: я обнаружил, что при выдаче исключения через границы службы WCF я должен выдать его как FaultExecption, иначе служба перейдет в неисправное состояние, хотя вы можете настроить тип ожидания повторного генерирования в качестве ошибки выполнения, я не могу указать конкретный тип исключения ошибки (например: FaultException‹ApplicationException›) в config. Я выбрасываю определенный тип, чтобы моя вызывающая служба могла поймать определенный тип исключения ошибки. Ваши комментарии: звук, если не выдвигать исключение через границы службы WCF, как я делаю - person Paul Berry; 08.07.2009