为什么win32exception没有被c#exception处理机制捕获

我有一个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()); } } } 

只要存在win32exception,此机制就会失败,并且会抛出未处理的exception消息并且应用程序崩溃。
关于此代码,我有两个问题:

1)为什么没有抓住win32exception。

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

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


因为Win32exception不是从.NET Exception类派生的。 试试:

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

有关详细信息,请参阅常规处理程序中的Catch non-CLSCompliantexception 。

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

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

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

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

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

  • AppDomain.CurrentDomain.UnhandledException
  • Application.ThreadException

然后你可以摆脱你的try catch块。


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

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

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

我似乎记得Win32Exceptioninheritance自ExternalException,但ExternalException不inheritanceException,因此不会被您的代码捕获。

编辑:看到其他答案为什么这是错的!

编辑2:至于第二部分,正如AnthonyWJones所述,让用户知道问题导致应用程序关闭是很好的方式,但我建议对用户使用简单的英语语句,并记录exception堆栈到日志文件供您自己使用。

1)应该捕获Win32exception。 也许从后台线程或GC线程抛出exception?

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