Загадка цикла обработки исключений

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

Я недавно добавил обработку исключения к приложению как своего рода нейтрализация в случае необработанных исключений. Я в основном обрабатываю ThreadException и UnhandledException как показано ниже:

// Add the event handler for handling UI thread exceptions to the event.
Application.ThreadException += new ThreadExceptionEventHandler(ExceptionHandler.OnUIThreadException);

// Set the unhandled exception mode to force all Windows Forms errors to go through
// our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

// Add the event handler for handling non-UI thread exceptions to the event. 
AppDomain.CurrentDomain.UnhandledException +=
    new UnhandledExceptionEventHandler(ExceptionHandler.OnUnhandledException);

// Runs the application.
Application.Run(new ErrorHandlerForm());

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

//code in some method of the Program
try
{
   foo.SomeFooCall();
}
catch(Exception ex)
{
  logger.Log(ex.Message);
  // I don't swallow!
  throw;
}

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

Когда и исключение брошен где-нибудь в вызове нечто, оно, очевидно, поймано кодом выше, зарегистрировано тогда брошенное снова. В этой точке ExceptionHandling вталкивает, делает некоторый вход, и уведомление (простой messagebox) тогда идет Application.Exit(). Что происходит, затем то, что приложение возвратится на том же throw который инициирует обработку ошибок с теми же результатами, и это продолжится неоднократно, пока она не откажет, по-видимому, потому что отслеживание стека полно, или она так или иначе обнаруживает бесконечный цикл.

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

Я ожидаю, что ответ на это мог бы быть тривиальным (или я могу отсутствовать, что-то очевидное) - кроме любых указателей/объяснений будет высоко цениться.

Править: Методы обработчиков исключений удаляют оба вызова к методу OnException, который идет что-то как:

private void OnUIThreadException(object sender, ThreadExceptionEventArgs e)
{
   OnException(e.Exception);
}

private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
   OnException((Exception)e.ExceptionObject);
}

private void OnException(Exception exception)
{
   MessageBox.Show("Fatal Exception: " + exception.Message);

   logger.Log(LoggingLevel.FATAL, "myLousyApp", exception.Message);

   Application.Exit();
}

Я на самом деле делаю smt больше, чем просто, что - такие как выяснение у пользователя, если они хотят перезапустить приложение и раз так перезапуск его с идентификатором процесса как cmd аргумент так, чтобы, когда это перезапускает, это ожидало старого процесса для выхода (это защищено от экземпляров дубликатов до взаимного исключения). Но для этого вопроса это не важно, так как я не перезапускаю приложение, когда я испытываю описанное поведение.

Править: Я создал другое простое приложение для репродуцирования, это обусловливает - у меня есть простой компонент, который выдает исключения (я бросаю произвольное число исключения в цикле), но во всех моих тестах на Приложении. Выйдите приложение просто закрывается приятно, и я не могу воспроизвести его. Озадаченный относительно того, что я должен искать!

15
задан JohnIdol 15 January 2010 в 17:55
поделиться

2 ответа

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

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

3
ответ дан 1 December 2019 в 03:14
поделиться

Я подозреваю, что в ExceptionHandler.OnunandledledException Новое исключение может быть поднято, что остается необработанным, пузырится до необработанного обработчика исключений, что повышает ваш ExceptionHandler.OnunhdledException метод на .. (бесконечная петля -> переполнение стека).

Так что Doublecheck ваш метод onunhandledexception для брошенных ошибок.

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

0
ответ дан 1 December 2019 в 03:14
поделиться
Другие вопросы по тегам:

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