【问题标题】:NullReferenceException with no stack trace when hooking SetConsoleCtrlHandler挂钩 SetConsoleCtrlHandler 时没有堆栈跟踪的 NullReferenceException
【发布时间】:2011-07-21 22:27:44
【问题描述】:

使用代码从this thread 挂钩控制台关闭事件,我有时会得到一个没有堆栈跟踪的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 透露了一些 bugsissuesSetConsoleCtrlHandler,所以我想知道这是否是一场失败的战斗。

【问题讨论】:

    标签: c# console hook


    【解决方案1】:

    此类代码最典型的问题是没有保留对委托实例的引用。作为第一个参数传递给 SetConsoleCtrlHandler() 的那个。垃圾收集器看不到非托管代码对委托对象的引用。所以这最终会在垃圾收集器运行时爆炸:

     SetConsoleCtrlHandler(Handler, true);
    

    完全一样
     SetConsoleCtrlHandler(new EventHandler(Handler), true);
    

    假设您使用了链接代码中的类型。该代码的作者通过使 _handler 成为静态变量来小心地避免了这个问题。与前两行代码创建的临时委托实例相反。将它存储在静态变量中可确保它在程序的生命周期内保持引用。在这种特殊情况下要做正确的事情,因为在程序结束之前您实际上对事件感兴趣。

    【讨论】:

    • 这很有意义,因为我有时会收到“尝试读取或写入受保护的内存”。我实际上是在使用你的代码 :) stackoverflow.com/questions/4646827/…
    • 这大约是我承诺的大约一百五十瓶啤酒之一的价值。这是你的,干杯。
    • 干杯!我明天一到办公室就接受:)
    • 这可能让我免于调试很多小时。谢谢!
    【解决方案2】:

    对于正在为此苦苦挣扎的 vb.net 开发人员,我的代码是...

    'declaration
    Private Declare Function SetConsoleCtrlHandler Lib "kernel32" (ByVal handlerRoutine As ConsoleEventDelegate, ByVal add As Boolean) As Boolean
    Public Delegate Function ConsoleEventDelegate(ByVal [event] As ConsoleEvent) As Boolean
    
    'The close function...
    Public Function Application_ConsoleEvent(ByVal [event] As ConsoleEvent) As Boolean
        Console.WriteLine("We're closing it all down: ")
        Return False
    End Function
    
    'creating the handler. 
    If Not SetConsoleCtrlHandler(New ConsoleEventDelegate(AddressOf Application_ConsoleEvent), True) Then
        Console.WriteLine("Unable to install console event handler.")
        Exit Sub
    End If
    

    【讨论】:

      猜你喜欢
      • 2016-01-28
      • 1970-01-01
      • 1970-01-01
      • 2012-01-18
      • 1970-01-01
      • 1970-01-01
      • 2021-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多