3

我正在使用 WPF 窗口开发 Word 加载项。我正在使用 UnhandledExceptionFilter 来捕获任何未处理的异常,以便 Word 不会引发错误消息。

Dispatcher.CurrentDispatcher.UnhandledExceptionFilter += new DispatcherUnhandledExceptionFilterEventHandler(Dispatcher_UnhandledExceptionFilter);

void Dispatcher_UnhandledExceptionFilter(object sender, DispatcherUnhandledExceptionFilterEventArgs e)
{
  e.RequestCatch = false;
  // Display error message and close the window.
}

我的事件被正确触发,我可以显示相应的错误消息框。但是,对于某些异常(例如窗口代码中的空指针异常),异常仍然被抛出给调用类。而其他异常(例如,从窗口中使用的另一个帮助程序类抛出的 EndpointNotFoundException)在我的事件中被捕获并且不会被重新抛出。

有什么想法吗?谢谢。

我问了一个关于如何捕获未处理异常的初始问题,但现在我遇到了这个额外的问题。

在 Microsoft 显示错误消息之前,在 Word 加载项中捕获 C# WPF 未处理的异常

4

1 回答 1

0

我通过使用 3 个不同的异常处理程序来解决此问题,具体取决于抛出异常的方式和位置,您需要单独捕获它。这也使您有机会根据您自己对异常是否致命的决定来取消终止并继续程序执行。

using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
    
public class ExceptionHelper
{
    public static ExceptionHelper()
    {
        TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;
        Application.Current.Dispatcher.UnhandledException += DispatcherOnUnhandledException;
        AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;
    }

    private static void TaskSchedulerOnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
    {
        e?.SetObserved();
        CurrentDomainUnhandledException(sender, new UnhandledExceptionEventArgs(e.Exception, false));
    }
    
    private static void DispatcherOnUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
    {
        e.Handled = true;
        CurrentDomainUnhandledException(sender, new UnhandledExceptionEventArgs(e.Exception, false));
    }
    
    public static void CurrentDomainUnhandledException(object sender, [CanBeNull] UnhandledExceptionEventArgs e)
    {
        //Program is hung, ensure we don't infinite loop on outofmemory exception by removing the handler
        var isTerminating = e?.IsTerminating == true;
    
        if (isTerminating)
        {
            TaskScheduler.UnobservedTaskException -= TaskSchedulerOnUnobservedTaskException;
            Application.Current.Dispatcher.UnhandledException -= DispatcherOnUnhandledException;
            AppDomain.CurrentDomain.UnhandledException -= CurrentDomainUnhandledException;
        }
    
        var ex = (Exception)e?.ExceptionObject;
        
        
        //Kill the app if we weren't already terminating and the program is in a corrupted state.

        if(!isTerminating)
            Process.GetCurrentProcess().Kill();
    
    }
}
于 2020-12-02T00:51:41.130 回答