2015-09-04 1 views
2

У меня следующий обработчик ошибок в моей консольного приложенияПолучение ExitCode Из Exception Handler

Главная Процедура:

AppDomain.CurrentDomain.UnhandledException += 
       new UnhandledExceptionEventHandler(ErrorHandler); 

Handler Процедура:

static void ErrorHandler(object sender, UnhandledExceptionEventArgs args) 
     { 
      Exception e = (Exception)args.ExceptionObject; 
      ... Loging Error ... 
      //Environment.Exit(?); 
     } 

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

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

Спасибо

+0

посмотреть, есть ли [лучшая альтернатива «Включение ошибки в следующем порядке» для C#?] (Http: // stackoverflow.com/questions/4825422/what-is-the-best-alternative-on-error-resume-next-for-c) help –

ответ

1

Можете ли вы использовать Исключение. HResult?

Рассмотрим следующий код:

class Program 
{ 
    static int Main(string[] args) 
    { 
     AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; ; 

     if (args.Any() && args[0] == "/t") 
     { 
      Console.WriteLine("I am going to throw an exception"); 

      throw new ApplicationException("This is an exception"); 
     } 
     else 
     { 
      Console.WriteLine("I am going to exit"); 
      //Environment.Exit(0); 
      return 0; 
     } 
    } 

    private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
    { 
     Console.WriteLine("An unexpected error has occurred"); 
     Exception ex = (Exception)e.ExceptionObject; 

     Environment.Exit(ex.HResult); 
    } 

} 

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

@echo off 
cls 
echo Running Console Application with no error 
ConsoleApplication2.exe 
echo %errorlevel% 

echo Running Console Application with error 
ConsoleApplication2.exe /t 
echo %errorlevel% 
pause 

В первом запуске вы выходите с 0. Я сделал Main return int и просто вернул 0 для успешного выполнения - вы можете сделать Environment.Exit (0) здесь.

С помощью второго запуска, который генерирует исключение ApplicationException, обрабатывается UnhandledException, вызывается Environment.Exit (ex.HResult).

Я думаю, что HResult привязан к определенным исключениям в соответствии с MSDN. Однако вам могут потребоваться разные коды выхода в зависимости от того, что вызвало исключение. В этом случае вы можете бросить пользовательские исключения, то есть cafuffled логика в обработчике UnhandledException:

private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
    { 
     Console.WriteLine("An unexpected error has occurred"); 
     Exception ex = (Exception)e.ExceptionObject; 
     if (ex is MyException) 
     { 
      Environment.Exit(10009); // my own exit codes 
     } 

     Environment.Exit(ex.HResult); 
    } 

} 

class MyException : Exception 
{ 

} 

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

+0

Спасибо, я не буду использовать информацию об определенном ExitCode, но я хотел, чтобы это было правильно и в будущем это может быть полезно. Несмотря на то, что я обнаружил, что приложение все равно рушится, но это не очень важно, потому что он регистрирует :-) – Muflix

3

Большинство программистов просто использовать Environment.Exit (1). Почти всегда работает отлично. Но это не является технически корректным, если программа умирает от исключения, тогда ее код выхода обычно такой же, как и исходный код ошибки исключения. Обработчик событий не должен изменять это поведение.

Делать это право является громоздко:

Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(e)); 

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