我有一个本机 Visual C++ NT 服务。当服务启动时,它的线程调用CoInitialize()
它将线程附加到 STA - 服务线程通过 COM 接口使用 MSXML。
当服务接收到SERVICE_CONTROL_STOP
它在消息队列中发布一条消息,然后检索该消息并OnStop()
处理程序被调用。处理程序清理东西并调用CoUnitialize()
。大多数时候它工作正常,但有时后一个调用会挂起。我无法稳定地重现这种行为。
我用谷歌搜索了一段时间,发现了以下可能的解释:
- 无法释放拥有的所有 COM 对象
- 反复呼唤CoInitializeEx()/CoUnitialize()用于连接到 MTA http://support.microsoft.com/kb/293278
- 无法在 STA 线程中分派消息 http://support.microsoft.com/default.aspx?scid=kb;en-us;136885
第一个不太可能 - 使用 MSXML 的代码经过了充分的测试和分析,并且它使用智能指针来控制对象的生存期,因此泄漏对象确实不太可能。
第二个看起来不像是可能的原因。我附加到 STA 并且不会重复调用这些函数。
第三种可能性看起来或多或少是有可能的。当线程处理消息时,它不再运行消息循环 - 它已经在循环内。我想这可能是原因。
后者是这个问题的可能原因吗?我还应该考虑哪些其他原因?我如何轻松解决这个问题?
不要这样做anything在处理 SCM 消息的线程中,它处于一个奇怪的神奇上下文中 - 您必须尽快答复 SCM 的请求,而不采取任何阻塞操作。通过 STOP_PENDING 告诉它您需要额外的时间,将另一个线程排队以进行真正的清理,然后立即完成 SCM 消息。
至于 CoUninitialize,只需附加 WinDbg 并转储所有线程 - 死锁很容易诊断(也许无法修复!),您已经在堆栈中找到了所有犯罪方。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)