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_UnhandledException
和 Marshal.GetExceptionPointers ();
正确 returns 一个指针。
而如果异常发生在UI线程,例如:
throw new Exception("UI thread");
然后Current_DispatcherUnhandledException
被执行并且GetExceptionPointers
returns IntPtr.Zero
.
问题:
如何在 UI
中的异常中获得 ExceptionPointers
?
找到解决方案:
使用 Current.Dispatcher.UnhandledExceptionFilter
而不是 Current.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_UnhandledException
和 Marshal.GetExceptionPointers ();
正确 returns 一个指针。
而如果异常发生在UI线程,例如:
throw new Exception("UI thread");
然后Current_DispatcherUnhandledException
被执行并且GetExceptionPointers
returns IntPtr.Zero
.
问题:
如何在 UI
中的异常中获得 ExceptionPointers
?
找到解决方案:
使用 Current.Dispatcher.UnhandledExceptionFilter
而不是 Current.DispatcherUnhandledException
。