在线程中抛出的未处理异常不会被捕获
本文关键字:异常 未处理 线程 | 更新日期: 2023-09-27 18:19:03
我正在研究一个使用普通threads
实现的项目。应用程序中大多数预期的异常都得到了处理,然而,在某些情况下,其中一个线程抛出了一个意外的异常,应用程序只是崩溃了(应用程序是基于I/O
和Client-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
。不幸的是,我不能改变应用程序的结构,这意味着我不能使用任务并行库。我不明白为什么这行不通。是否有其他方法来处理线程中抛出的异常?
你的方法是正确的。但是,您将无法阻止应用程序终止。
当一个未处理的异常被抛出到你在应用程序中创建的线程时,CurrentDomain_UnhandledException
将被调用,允许你记录或报告异常。但是,除非e.IsTerminating
是false
,否则您将无法阻止应用程序的终止。您可以在托管线程中的异常中了解更多有关此行为的信息。
如果您发现CurrentDomain_UnhandledException
从未被调用,您应该验证是否调用了Application_Startup
来设置处理程序。
如果你仍然有问题,你应该验证Utilities.DisplayUnhandledException
没有抛出异常。这也将导致您的申请立即终止。特别是,如果e.ExceptionObject
不是Exception
类型,将其转换为Exception
将抛出异常。但是,在正常情况下,当异常对象不是托管异常时,它将被包装在RuntimeWrappedException
中。
为了避免终止应用程序,你需要在线程方法的"堆栈顶部"捕获异常。如果因为无法访问代码而无法做到这一点,那么未处理的异常就是软件有bug的指示,即使发现软件bug很不方便,最好的做法是终止应用程序以避免损坏。