c# – .NET中非托管线程的异常
如何处理我的应用程序终止时的情况,在终止之前使用回调?
.NET处理程序在以下场景中不起作用,SetUnhandledExceptionHandler是正确的选择吗?它似乎具有以下讨论的缺点. 脚本 我想回复所有应用程序终止的情况,并在我们的.net应用程序中向我们的服务发送消息和错误报告. 但是,我有一个WPF应用程序,其中我们的两个测试人员获得绕过的未处理异常: > AppDomain.UnhandledException(最重要的) 它们标记为SecuirtyCritical和HandleProcessCorruptedStateExceptions. 我在野外的两个例子 >在某个地方初始化WPF时,运行widows10的VirtualBox会抛出一些vboxd3d.dll(关闭vbox 3d accel“修复它”) 无论哪种方式,当实时,应用程序必须在终止之前响应这些类型的故障. 我可以使用非托管异常重现这一点,该异常发生在.net中的PInvoked方法的非托管线程中: Test.dll的 BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } DWORD WINAPI myThread(LPVOID lpParameter) { long testfail = *(long*)(-9022); return 1; } extern "C" __declspec(dllexport) void test() { DWORD tid; HANDLE myHandle = CreateThread(0,myThread,NULL,&tid); WaitForSingleObject(myHandle,INFINITE); } APP.EXE class TestApp { [DllImport("kernel32.dll")] static extern FilterDelegate SetUnhandledExceptionFilter(FilterDelegate lpTopLevelExceptionFilter); [UnmanagedFunctionPointer(CallingConvention.StdCall)] delegate int FilterDelegate(IntPtr exception_pointers); static int Win32Handler(IntPtr nope) { MessageBox.Show("Native uncaught SEH exception"); // show + report or whatever Environment.Exit(-1); // exit and avoid WER etc return 1; // thats EXCEPTION_EXECUTE_HANDLER,although this wont be called due to the previous line } [DllImport("test.dll")] static extern void test(); [STAThread] public static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); SetUnhandledExceptionFilter(Win32Handler); test(); // This is caught by Win32Handler,not CurrentDomain_UnhandledException } [SecurityCritical,HandleProcessCorruptedStateExceptions ] static void CurrentDomain_UnhandledException(object sender,UnhandledExceptionEventArgs e) { Exception ex = e.ExceptionObject as Exception; MessageBox.Show(ex.ToString()); // show + report or whatever Environment.Exit(-1); // exit and avoid WER etc } } 这可以处理裸WPF测试应用程序中vboxd3d.dll的失败,当然还有WCF Dispatcher和WinForms Application(为什么不)注册的异常处理程序. 更新 >在我试图使用它的生产代码中,处理程序似乎被其他调用者覆盖,我可以通过每100ms调用该方法来解决这个问题,当然这是愚蠢的. >在出现vbox3d.dll问题的计算机上,执行上述操作会将异常替换为clr.dll中的异常. 解决方法
问题中代码的问题是:
SetUnhandledExceptionFilter(Win32Handler); 由于委托是自动创建的,因此请注意: FilterDelegate del = new FilterDelegate(Win32Handler); SetUnhandledExceptionFilter(del); 问题是,GC可以收集它,以及在最终引用之后的任何时刻创建的本机>托管thunk.所以: SetUnhandledExceptionFilter(Win32Handler); GC.Collect(); native_crash_on_unmanaged_thread(); 总是会导致令人讨厌的崩溃,其中传递给kernel32.dll的处理程序不再是有效的函数指针.这可以通过不允许GC收集来解决: public class Program { static FilterDelegate mdel; public static void Main(string[] args) { FilterDelegate del = new FilterDelegate(Win32Handler); SetUnhandledExceptionFilter(del); GC.KeepAlive(del); // do not collect "del" in this scope (main) // You could also use mdel,which I dont believe is collected either GC.Collect(); native_crash_on_unmanaged_thread(); } } 其他答案也是一个很好的资源;不知道现在要回答什么. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |