2013-06-20 46 views
2

我正在使用普通的threads实现的项目。应用程序中的大多数预期异常都会被处理,但是,有些线程会引发意外的异常并导致应用程序崩溃(应用程序同时基于I/OClient-Server,因此实际上不可能处理所有异常)。在线程中抛出未处理的异常不会被捕获

为了解决这个问题,我试图定义一个全局的UnhandledExceptionHandler,以便应用程序显示一个友好的消息而不是崩溃。这是我试过的:

public partial class App : Application 
{ 
    private void Application_Startup(object sender, StartupEventArgs e) 
    { 
     AppDomain.CurrentDomain.UnhandledException += 
      new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 

     // The rest of the startup logic goes here 
    } 

    void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
    { 
     Utilities.DisplayUnhandledException((Exception)e.ExceptionObject); 
    } 
} 

虽然这不起作用。 CurrentDomain_UnhandledException永远不会被调用。不幸的是,我无法改变应用程序的结构,这意味着我无法使用任务并行库。我无法弄清楚为什么这不起作用。有没有其他方法来处理线程中抛出的异常?任何帮助表示赞赏。

+0

尝试'Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);'和'Application.ThreadException + = Application_ThreadException;' – Blorgbeard

+0

这里有一些彻底的解释:http://stackoverflow.com/questions/1472498/wpf-global-exception-handler –

回答

3

你的方法是正确的。但是,您将无法停止应用程序的终止。

当您在应用程序CurrentDomain_UnhandledException中创建的线程上抛出未处理的异常时,将会调用您允许您记录或报告异常。但是,除非e.IsTerminatingfalse,否则您将无法停止应用程序的终止。您可以在Exceptions in Managed Threads中阅读有关此行为的更多信息。

如果您发现CurrentDomain_UnhandledException从未被调用,则应验证调用Application_Startup来设置处理程序。

如果仍有问题,应验证Utilities.DisplayUnhandledException不会引发异常。这也将导致您的应用程序立即终止。特别是,如果e.ExceptionObject不是Exception类型,则将其转换为Exception将引发异常。但是,在正常情况下,当异常对象不是托管异常时,it will be wrapped in a RuntimeWrappedException

为了避免终止您的应用程序,您需要捕获线程方法“栈顶”处的异常。如果因为无法访问代码而无法实现这一点,则未处理的异常表明存在错误的软件,即使发现软件错误时最好的做法是不方便,也应该终止应用程序以避免损坏。

相关问题