我们有一个 .NET 3.5 程序集 (dll),由 VB6“代理”(exe) 通过 COM 接口执行。 VB6 代码确实调用:
' Ensure that no system dialog comes up when we GPF.
PreviousErrorMode = SetErrorMode(SEM_NOGPFAULTERRORBOX)
SetErrorMode PreviousErrorMode Or SEM_NOGPFAULTERRORBOX
' Assign our Exception Handler for this process.
PreviousExceptionFilter = SetUnhandledExceptionFilter(AddressOf UnhandledExceptionFilter)
还有VB6UnhandledExceptionFilter
将异常转换为 VB6 引发的错误。 (但是这里也没有调用它,并且这个 VB6 代码多年来没有被更改,甚至没有重新编译。)
在 VB6 代码创建的第一个 .NET 对象的构造函数中,我添加了一个处理程序AppDomain.CurrentDomain.UnhandledException
(并且,在尝试调试这个问题时,我添加了一个Windows.Forms.Application.ThreadException
,但这并没有帮助,无论如何我们都没有通过 .NET 显示任何 UI)。
我确信UnhandledException
在 VS2008 中开发这段代码时,事件捕获了一些东西,但我不确定我是否在 VS2015 中看到过它。
该代码运行多个线程,其中一些线程正在执行主要目的,其中涉及插入和更新 SQL Server 数据,并且还通过 TCP 协议进行通信,该协议由其他线程处理,包括BackgroundWorker
.
那些执行主要目的的创建者是:
taskThread = New Thread(AddressOf EnsureTaskCompletes)
taskThread.SetApartmentState(Threading.ApartmentState.STA)
taskThread.Start()
它太专有和复杂,无法向您展示更多代码,但我在调试此问题时调整了代码以简单地Throw New Exception
而不是最终具有相同效果的复杂代码。(*)
这个“简单”异常没有被处理UnhandledExceptionHandler
除非我打开了非托管调试,否则就会默默地终止程序。
是否有记录的行为改变AppDomain.CurrentDomain.UnhandledException
当.NET Framework“仅”作为 dll 加载时?
(由于COM重新注册,我不想在VS2008中构建以前的版本尚未确认is行为改变。我have确认.NET 3.5Exe由 VS2015 编译,创建一个Thread
引发未处理的异常does处理异常UnhandledException
event.)
我的解决方法是添加一个Catch
到现有的Try Finally
in EnusreTaskCompletes
已经尝试至少记录线程在任务完成之前终止,并调用UnhandledExceptionHandler
myself.
(*实际问题是数据库中缺少一个表,该表仅在信用用完时使用 - 我没有添加该代码或表。这引发了一个异常,但该异常未被捕获UnhandledExceptionHandler
,使得调试变得相当困难——SQL Server Profiler终于发现了这个问题。)