为什么win32异常没有被c#异常处理机制捕获

时间:2009-07-30 09:17:35

标签: c# winforms exception-handling

我有一个winforms应用程序。从Program.cs开始,我们已经定义了main()。我已将此代码放在try-catch块中。

 [STAThread]
    static void Main()
    {
        try
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new frmSplash());
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            if (ex.InnerException != null)
            {
                MessageBox.Show(ex.InnerException.ToString());
            }
        }
    }

每当出现win32异常时,此机制将失败并抛出未处理的异常消息并且应用程序崩溃。
关于此代码,我有两个问题:

1)为什么没有抓住win32异常。

2)在最高级别捕获异常是一种好习惯。

6 个答案:

答案 0 :(得分:13)

编辑:正如Pratik所指出的,以下答案仅适用于.NET 1.0和.NET 1.1。从.NET 2.0开始,非CLS异常应该被捕获为RuntimeWrappedException


因为Win32异常不是从.NET Exception类派生的。试试:

try {
} catch (Exception ex) {
    // .NET exception
} catch {
    // native exception
}

有关详细信息,请参阅Catch non-CLSCompliant exceptions in general handlers

答案 1 :(得分:3)

Application.Run的执行不会引发错误。这发生在另一个线程上(或至少是异步的)。

最好以友好的方式通知用户应用程序在完全消失之前已经失败,但是抓住然后继续它并不是一个好主意。

答案 2 :(得分:3)

虽然我不知道为什么你的catch块不起作用但尝试使用Application ThreadException Event。这应该捕获应用程序线程中的任何错误。在调用Application.Run之前添加事件处理程序。

对于你的第二个回答肯定是的。我开发并维护一个企业winforms应用程序,它与后台线程上的Web服务后端进行通信。如果任何webservice调用崩溃处理应用程序threadexception(以及appdomain unhandledexception)事件,请记录并弹出业务用户可以报告的错误,并允许它们继续运行而不会使应用程序崩溃。

答案 3 :(得分:2)

尝试在应用程序启动前订阅这些事件(Application.Run):

然后你可以摆脱try catch阻止。


我认为在最高级别捕获异常是不好的做法,但你无法避免它!在开发(调试)期间,不应该捕获这些异常,应用程序应该尽可能地做最糟糕的事情(崩溃?)。在生产(发布)中,即使出现未处理的异常,您也希望应用程序尽可能地降级。这是我为DEBUG preprocessor variable找到的少数用途之一。

答案 4 :(得分:0)

您可能需要捕获Win32Exception(或ExternalException)而不是

http://msdn.microsoft.com/en-us/library/system.componentmodel.win32exception.aspx

我似乎记得Win32Exception继承自ExternalException,但ExternalException不会从Exception继承,因此不会被您的代码捕获。

修改:请参阅其他答案,了解这是错误的原因!

编辑2:至于第二部分,正如AnthonyWJones所述,让用户知道某个问题导致应用程序关闭是一种礼貌,但我建议使用简单的英语对用户的声明,并将异常堆栈记录到日志文件中供您自己使用。

答案 5 :(得分:0)

1)应该捕获Win32异常。也许从后台线程或GC线程抛出异常?

2)这取决于您的应用结构。例如,如果您的错误通知UI以某种方式绑定到主窗体(例如,您需要从工作线程调用UI线程),那么在运行该消息的代码之外的代码块中显示UI将是愚蠢的环。但是,如果你的代码示例是单线程的,那就没关系。