Dav*_*vy8 24 c# keyboard-hook setwindowshookex
我们必须通过安装一些全局键盘钩子SetWindowsHookEx与WH_KEYBOARD_LL看似随机获得由Windows脱钩.
我们验证了它们不再附加钩子,因为调用UnhookWindowsHookEx句柄返回false.(还验证了它true在正常工作时返回)
似乎没有一致的repro,我听说他们可以因为超时或异常被抛出而脱钩,但我已经尝试了两个只是让它在处理方法中断点超过一分钟,以及抛出一个随机异常(C#),它似乎仍然有效.
在我们的回调中,我们快速发布到另一个线程,这可能不是问题.我已经阅读了Windows 7中的解决方案,用于在注册表中设置更高的超时,因为Windows 7显然更加积极地执行超时(我们都在这里运行Win7,所以不确定这是否发生在其他操作系统上),但这并不是看起来似乎是一个理想的解决方案.
我考虑过只运行一个后台线程来每隔一段时间刷新一次钩子,这很黑,但我不知道这样做有什么真正的负面后果,而且它似乎比改变全局Windows注册表设置更好.
还有其他建议或解决方案? 设置挂钩的类和它们所附加的委托都是静态的,因此它们不应该是GC.
编辑:通过调用验证GC.Collect();他们仍然有效,因此他们没有被收集的垃圾.
MZB*_*MZB 16
我认为这必须是一个超时问题.
其他开发人员报告了一个Windows7特定问题,如果低级挂钩超过(未记录的)超时值,则会解除挂钩.
对于讨论相同问题的其他开发人员,请参阅此主题 可能是您需要执行繁忙循环(或慢速垃圾收集)而不是睡眠以导致取消吊钩行为.LowLevelKeyboardProc函数中的断点也可能会产生超时问题.(还有一种观察结果表明,另一项任务导致的CPU负载过重可能会引发这种行为 - 可能是因为其他任务从LowLevelKeyboardProc函数中窃取了CPU周期并导致其耗时太长.)
该线程中建议的解决方案是尝试将HKEY_CURRENT_USER\Control Panel\Desktop中的注册表中的LowLevelHooksTimeout DWORD值设置为更大的值.
请记住,C#的一个荣耀是,如果发生垃圾收集,即使是简单的语句也会占用过多的时间.这(或其他线程的CPU加载)可能会解释问题的间歇性.