【问题标题】:Getting ExitCode From Exception Handler从异常处理程序获取 ExitCode
【发布时间】:2015-09-04 09:43:14
【问题描述】:

我的控制台应用程序中有以下错误处理程序

主要程序:

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

处理程序:

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

问题是记录了错误,但在该应用程序失败并显示窗口弹出(应用程序没有响应)之后。

所以我想添加 Environment.Exit() 来防止这种行为,但是如何从异常中指定 exitCode 呢?我不想设置 Exit(0) (这意味着一切正常),因为我还想在触发此脚本的调度程序应用程序中查看错误(仅发生某些错误的信息,已记录异常的信息)。

谢谢

【问题讨论】:

标签: c# exception exit-code


【解决方案1】:

大多数程序员只使用 Environment.Exit(1)。几乎总是工作得很好。但这在技术上是不正确的,如果程序因异常而死,那么它的退出代码通常与底层异常错误代码相同。事件处理程序不应该改变这种行为。

做对了就是拗口:

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

这里有一个 FUD 因素,您不能完全信任具有未设置错误代码的自定义异常对象的库。还可以,回退是 E_FAIL。

【讨论】:

    【解决方案2】:

    你可以使用 Exception.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);
        }
    
    }
    

    然后从批处理文件中执行两次 - 一次使用 /t 参数,另一次不使用:

    @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 返回一个 int 并仅返回 0 以成功执行 - 您可以在此处执行 Environment.Exit(0)。

    在引发 ApplicationException 的第二次运行中,处理 UnhandledException,然后调用 Environment.Exit(ex.HResult)。

    我认为 HResult 与 MSDN 中的特定异常有关。但是,您可能需要不同的退出代码,具体取决于导致异常的原因。在这种情况下,您可以抛出自定义异常,然后在 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
    {
    
    }
    

    但你真的会关心它为什么在控制台中失败吗?如果你得到一个未处理的异常,那么它就失败了。您可能有很多可能的故障点。你真的要对错误代码做什么?您已将异常注销。这提供了重要信息。

    【讨论】:

    • 谢谢,我不会使用有关特定 ExitCode 的信息,但我希望它正确,并且在将来它会很有用。尽管我发现应用程序无论如何都会崩溃,但这并不是什么大问题,因为它正在记录:-)
    猜你喜欢
    • 1970-01-01
    • 2017-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    • 1970-01-01
    相关资源
    最近更新 更多