在 WPF 的子线程中捕获未处理的异常

Posted

技术标签:

【中文标题】在 WPF 的子线程中捕获未处理的异常【英文标题】:Catching Unhandled Exceptions in Child Threads in WPF 【发布时间】:2010-11-28 13:25:37 【问题描述】:

我有一个分离多个线程的 WPF 应用程序。我在 App.xaml.cs 中定义了一个 DispatcherUnhandledException 事件处理程序,它显示详细的错误消息,并且每次 UI 线程遇到异常时都会调用此处理程序。问题出在子线程上:它们未处理的异常永远不会得到处理。我该怎么做?

示例代码:

private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)

    MessageBox.Show("detailed error message");


private void Application_Startup(object sender, StartupEventArgs e)

    //...
    //If an Exception is thrown here, it is handled
    //...

    Thread[] threads = new Thread[numThreads];
    for(int i = 0; i < numThreads; i++)
    
        threads[i] = new Thread(doWork);
        threads[i].Start();
    


private void doWork()

    //...
    //Exception thrown here and is NOT handled
    //...

编辑:一旦发生未处理的异常,我想显示带有堆栈跟踪的错误消息,然后退出应用程序。

【问题讨论】:

【参考方案1】:

也尝试连接到AppDomain.CurrentDomain.UnhandledException 事件。

【讨论】:

请参阅msdn.microsoft.com/en-us/library/… 了解为什么它只能用于在退出前记录错误。 @Henk,那是我已经发布的同一个链接。不过你是对的,异常应该只用于记录目的。 Brandon,好的,我没有检查你的链接(-:但是每个线程都应该处理它自己的异常。【参考方案2】:

这是设计使然,您应该在 DoWork 的顶层使用 try/catch。一些线程模型迎合了这一点,以 Backgroundworker 为例。

.NET 4 Task 类为这个问题提供了一个很好的接口。在此之前,您必须自己处理它,或者使用 BGW 或 IAsyncResult 模型。

【讨论】:

这是一个非常有效的答案,但对于我的特殊情况,我碰巧在 doWork() 中运行了一个漫长而复杂的过程。据我了解,try/catch 块会带来相当可观的性能损失,我更喜欢只在小块代码上使用它们。 不,try/catch 只影响性能抛出异常,然后速度通常不是你最大的问题。在正常情况下没有缺点。在线程中“逃脱”异常之后,整个应用程序的稳定性就会出现问题。

以上是关于在 WPF 的子线程中捕获未处理的异常的主要内容,如果未能解决你的问题,请参考以下文章

WPF异常捕获三种处理 UI线程, 全局异常,Task异常

Java多线程之捕获子线程中的异常---面试经

Java子线程中的异常处理(通用)

Android视图:未捕获的处理程序:线程主因未捕获的异常而退出

7.线程的八大核心基础知识之未捕获异常如何处理

面试官:线程池执行过程中遇到异常会发生什么,怎样处理?