挂钩 SetConsoleCtrlHandler 时没有堆栈跟踪的 NullReferenceException
使用代码从此线程挂钩控制台关闭事件,我有时会得到NullReferenceException
没有堆栈跟踪(大多数时候我没有)。它发生在发布和调试中,并且“抛出异常时中断”没有帮助(它中断,但堆栈跟踪仍然为空)。当我正常退出应用程序时(按下回车键并因此释放Console.ReadLine),我从未遇到此异常。应用程序事件日志有 2 个条目:
应用程序:MyApp.exe 框架版本:v4.0.30319 描述: 由于未处理的异常,该进程被终止。例外 信息:System.NullReferenceException 堆栈:
并且:
故障应用程序名称:Gateway.exe,版本:1.0.0.0,时间戳: 0x4e284101 故障模块名称:未知,版本:0.0.0.0,时间 标记:0x00000000 异常代码:0xc0000005 故障偏移量:0x004d41ce 错误进程 ID:0xf00 错误应用程序启动时间: 0x01cc47b827e19a6e 错误的应用程序路径: C:\dev\MyApp.exe 错误模块路径: 未知报告 ID:689c1caa-b3ab-11e0-ba1b-00247e777f12
Google 已透露一些 错误和问题 与 SetConsoleCtrlHandler
,所以我想知道这是否是一场失败的战斗。
Using code to hook the console close event from this thread, I sometimes get a NullReferenceException
with no stacktrace (most of the times I don't). It happens in both release and debug and "break when an exception is thrown" doesn't help (it breaks, but the stack trace is still empty). I never get this exception when I exit my application normally (which is hitting enter and thus releasing a Console.ReadLine
). The Application event log has 2 entries:
Application: MyApp.exe Framework Version: v4.0.30319 Description:
The process was terminated due to an unhandled exception. Exception
Info: System.NullReferenceException Stack:
And:
Faulting application name: Gateway.exe, version: 1.0.0.0, time stamp:
0x4e284101 Faulting module name: unknown, version: 0.0.0.0, time
stamp: 0x00000000 Exception code: 0xc0000005 Fault offset: 0x004d41ce
Faulting process id: 0xf00 Faulting application start time:
0x01cc47b827e19a6e Faulting application path:
C:\dev\MyApp.exe Faulting module path:
unknown Report Id: 689c1caa-b3ab-11e0-ba1b-00247e777f12
Google has revealed some bugs and issues with SetConsoleCtrlHandler
, so I'm wondering if this is a lost battle.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
此类代码最典型的问题是没有保留对委托实例的引用。作为第一个参数传递给 SetConsoleCtrlHandler() 的那个。垃圾收集器无法看到非托管代码对委托对象的引用。因此,当垃圾收集器运行时,这最终会爆炸:
完全相同
这与假设您使用链接代码中的类型 。该代码的作者通过将 _handler 设置为静态变量来小心地避免了这个问题。与前两行代码创建的临时委托实例相反。将其存储在静态变量中可确保它在程序的生命周期内保持引用状态。在这种特殊情况下,正确的做法是因为您实际上对节目结束之前的事件感兴趣。
The most typical issue with code like that is not keeping a reference to the delegate instance. The one you pass as the first argument to SetConsoleCtrlHandler(). The garbage collector cannot see references held to a delegate object by unmanaged code. So this will, eventually, bomb when the garbage collector runs:
which is the exact same thing as
assuming you used the types in the linked code. The author of that code carefully avoided this issue by making _handler a static variable. As opposed to the temporary delegate instance that is created by the previous two lines of code. Storing it in a static variable ensures it stays referenced for the life of the program. The Right Thing to do in this particular case since you are actually interested in the events until the program ends.
对于正在为此苦苦挣扎的 vb.net 用户,我的代码是......
For the vb.net bods who are struggling with this, my code is ...