UnhandledExceptionFilter捕获所有异常但仅重新抛出一些异常

时间:2012-09-06 21:53:36

标签: wpf exception add-in dispatcher unhandled-exception

我正在使用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)在我的事件中被捕获而没有被重新抛出。

有什么想法?感谢。

我问了一个关于如何捕获未处理异常的初步问题,但现在我还有另外一个问题。

Catch C# WPF unhandled exception in Word Add-in before Microsoft displays error message

1 个答案:

答案 0 :(得分: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();
    
    }
}