Исключение рассматривается как необработанное пользователем, хотя оно обрабатывается - PullRequest
1 голос
/ 02 апреля 2012

Короткая версия:

Почему Visual Studio сообщает мне, что код выдал необработанное пользователем исключение, даже если я его перехватил?

Более длинная версия:

Я использую Entity Framework вместе с Основой Microsoft для обработки временных сбоев :

Мой класс Entity Framework является частичным, и у меня есть собственный метод SaveChangesWithRetries, где я выполняю повторные логики:

public partial class EfContext
{
    public virtual void SaveChangesWithRetries()
    {
       var retryPolicy = RetryPolicyFactory.GetDefaultSqlCommandRetryPolicy();
       retryPolicy.ExecuteAction(() =>
                       {
                          SaveChanges();
                       });
    }
 }

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

try
{
    context.SaveChangesWithRetries();
}
catch (OptimisticConcurrencyException)
{
    continue;
}

Несмотря на то, что я ловлю исключение OptimisticConcurrencyException, Visual Studio останавливает отладчик и сообщает мне, что вызов ExecuteAction () вызвал необработанное пользователем исключение. Когда это происходит, отладчик останавливается в классе EfContext. Если я нажму F10, отладчик переместится в ловушку (OptimisticConcurrencyException).

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

Ответы [ 2 ]

1 голос
/ 02 апреля 2012

Разобрался, что вызвало это.

  1. Наш код начал предложение try / catch
  2. Наш код, называемый Transient Fault Handling Framework (TFHF) *
  3. TFHF, вызвал наш код (через лямбда-выражение 9
  4. Наш код выдал исключение

Поскольку TFHF был встроен в выпуск, .NET Framework не понимал, что наш собственный код перехватил исключение на шаге 0, которое было сгенерировано на шаге 3.

0 голосов
/ 17 января 2013

У меня была похожая проблема, когда мне нужно было исключение для распространения через некоторый код .NET, чтобы я мог перехватить его с другой стороны. Я обнаружил, что диалоговое окно «Отладка> Исключения» позволяет вам выбрать, какие типы исключений вы хотите, чтобы VS нарушал. Для каждого типа исключения вы можете проверить, должно ли оно прерываться всякий раз, когда генерируется исключение, или только если оно не обработано. Итак, я выбрал эзотерический тип исключения, для которого «необработанный пользователь» не проверяется по умолчанию, и обернул исключение, которое я хотел распространить, с этим типом исключения. В частности, я выбрал исключение AppDomainUnloadedException, поскольку оно находится в сборке System.dll и, таким образом, уже упоминалось в моем проекте.

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

public override int Read(byte[] buffer, int offset, int count)
{
    try { return innerStream.Read(buffer, offset, count); }
    catch (IOException ex) { throw new AppDomainUnloadedException("Exception from innerStream: " + ex.Message, ex); }
}

А вот мой код, где я перехватываю его на другой стороне .NET-кода, через который он должен был распространяться:

try { bytesRead = sslStream.Read(buffer, offset, count); }
catch (Exception ex) { /* ex handled here. */ }

Проблема решена. VS больше не прерывается на innerStream.Read, когда он генерирует IOException.

...