2010-04-27 38 views
6

考虑以下简单的应用程序:在主捕捉异常()方法

public static void Main() 
{ 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 

    try 
    { 
     Application.Run(new Form1()); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("An unexpected exception was caught."); 
    } 

} 

Form1.cs中包含:通过在VS一个“新的C#视窗应用”序列是在一个下面的方式修改创建的窗口形式以下修改:

private void Form1_Load(object sender, EventArgs e) 
{ 
    throw new Exception("Error"); 

} 

如果我按F5在IDE中,然后,如我所料,我看到一个消息框说异常被捕获,并且应用程序退出。

如果我去调试(或释放)/斌并启动可执行文件,我看到标准的“未处理的异常”窗口,这意味着我的异常处理程序不起作用。

很明显,这与异常从Application.Run被调用的另一个线程抛出有关。但问题依然存在 - 为什么行为会因应用程序是从IDE还是从命令行运行而有所不同? 确保应用程序中没有未处理的例外的最佳做法是什么?

+0

@Corvin:如果你觉得你的问题得到了解决方案,请检查一个被接受的答案。 – 2010-04-28 06:55:11

回答

10

正常情况下,Application.ThreadException将处理Load事件中的异常。你将得到提供Quit和Continue选项的ThreadExceptionDialog。

但是,当连接调试器时不行。在这种情况下,显示对话框的消息循环中的catch子句被故意禁用。这是必要的,因为如果在调试程序时弹出对话框,将很难排除异常。哪个捕手不再活跃,您的Main()方法中的catch子句现在可以捕捉异常。

可以通过在Main()方法中使用Application.SetUnhandledExceptionMode()来使其一致。你不应该,如果你这样做,异常真的难以调试。如果您想自定义UI线程异常处理,那么你应该注册自己的Application.ThreadException处理程序:

if (!System.Diagnostics.Debugger.IsAttached) 
    Application.ThreadException += myThreadException; 

俘获工作线程未处理的异常需要AppDomain.UnhandledException处理程序。它们不可恢复。

还要小心64位Windows中的一个错误,当调试器被连接时,Load事件中的异常会被吞下而无需诊断。强制AnyCPU模式以避免陷阱。

+0

@Hans - 你是指'Form.Load'事件吗?顺便说一句,写得不错。 – 2010-04-28 06:56:39

+0

@彼得:是的。谢谢! – 2010-04-28 09:02:09