Marshal.GetExceptionPointers 和 DispatcherUnhandledException

Marshal.GetExceptionPointers and DispatcherUnhandledException

美好的一天。有一个 WPF application + dumper (MiniDumpWriteDump)。有必要在应用中出现UnhandledException时创建minidump然后放下应用

App.xaml.cs:

protected override void OnStartup(StartupEventArgs e)
    {
      base.OnStartup(e);
      AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
      Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
    }

[DllImport("Kernel32", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
public static extern Int32 GetCurrentWin32ThreadId();

private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
  var pointers = Marshal.GetExceptionPointers(); //everything is ok :)
  var thread = GetCurrentWin32ThreadId();
  handleAppException(e.ExceptionObject as Exception, thread, pointers);
}

private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
  var pointers = Marshal.GetExceptionPointers(); //here IntPtr.Zero :(
  var thread = GetCurrentWin32ThreadId();
  handleAppException(e.Exception as Exception, thread, pointers);
}

private void handleAppException(int threadId, IntPtr pointers)
{
  System.Threading.Tasks.Task.Factory.StartNew(() =>
  {
    MiniDump.CreateMiniDump("C:\Users\Public\Documents\dump.dmp", threadId, pointers);
  }).Wait();
}

如果发生与另一个线程关联的异常,例如:

  Thread t = new Thread(() =>
  {
    throw new Exception("Thread exception!");
  });
  t.Start();

然后 CurrentDomain_UnhandledExceptionMarshal.GetExceptionPointers (); 正确 returns 一个指针。 而如果异常发生在UI线程,例如:

throw new Exception("UI thread");

然后Current_DispatcherUnhandledException被执行并且GetExceptionPointers returns IntPtr.Zero.

问题: 如何在 UI 中的异常中获得 ExceptionPointers

找到解决方案:

使用 Current.Dispatcher.UnhandledExceptionFilter 而不是 Current.DispatcherUnhandledException