在线程中抛出的未处理异常不会被捕获。

12 浏览
0 Comments

在线程中抛出的未处理异常不会被捕获。

这个问题已经在这里有了答案:

WPF全局异常处理程序[重复]

我正在开发一个使用普通线程实现的项目。应用程序中大部分的预期异常都可以处理,但有些情况下,其中一个线程会抛出意外的异常,导致应用程序崩溃(应用程序基于I/O客户端 - 服务器,所以基本上无法处理所有异常)。

为了解决这个问题,我正在尝试定义一个全局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从不调用。不幸的是,我不能改变应用程序的结构,这意味着我不能使用Task Parallel Library。我想不出为什么这不能工作。有没有其他方法来处理在线程中抛出的异常?任何帮助将不胜感激。

admin 更改状态以发布 2023年5月24日
0
0 Comments

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

当在你的应用程序创建的线程上抛出未处理的异常时,CurrentDomain_UnhandledException 将被调用,允许你记录或报告异常。但是,除非 e.IsTerminatingfalse,否则你无法阻止应用程序终止。你可以在Managed Threads中的Exceptions中了解更多这种行为。

如果你发现 CurrentDomain_UnhandledException 从未被调用,你应该检查是否调用了 Application_Startup 来设置处理程序。

如果你仍然有问题,你应该验证 Utilities.DisplayUnhandledException 是否不会抛出异常。这也会导致应用程序立即终止。特别是,如果 e.ExceptionObject 不是 Exception 类型,将其转换为 Exception 将会抛出异常。然而,在正常情况下,当异常对象不是托管异常时,它将被包装在一个 RuntimeWrappedException

为了避免应用程序终止,你需要在线程方法的“栈顶”处捕获异常。如果这不可能,因为你无法访问该代码,那么未处理的异常就是有缺陷软件的标志,尽管这很不方便,但当发现软件中有错误时,最好的做法是终止应用程序以避免损坏。

0