如何解决挂在CoUnitialize()上的进程? [英] How do I resolve process hanging on CoUnitialize()?

查看:100
本文介绍了如何解决挂在CoUnitialize()上的进程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个本地Visual C ++ NT服务。服务启动后,其线程调用 CoInitialize()将该线程附加到STA-服务线程通过COM接口使用MSXML。

I have a native Visual C++ NT service. When the service is started its thread calls CoInitialize() which attaches the thread to an STA - the service thread uses MSXML through COM interfaces.

当服务收到 SERVICE_CONTROL_STOP 时,它将在消息队列中发布一条消息,然后稍后检索该消息并 OnStop() 处理程序被调用。处理程序清理东西并调用 CoUnitialize()。在大多数情况下,它都可以正常运行,但有时后者的调用会挂起。我无法稳定地重现此行为。

When the service receives SERVICE_CONTROL_STOP it posts a message in the message queue, then later that message is retrieved and the OnStop() handler is invoked. The handler cleans up stuff and calls CoUnitialize(). Most of the time it works allright, but once in a while the latter call hangs. I can't reproduce this behavior stably.

我搜索了一段时间,发现了以下可能的解释:

I googled for a while and found the following likely explanations:


  1. 无法释放所有拥有的COM对象

  2. 重复调用 CoInitializeEx() / CoUnitialize()附加到MTA

  3. 无法分派STA线程中的消息

  1. failing to release all COM objects owned
  2. repeatedly calling CoInitializeEx()/CoUnitialize() for attaching to MTA
  3. failing to dispatch messaged in STA threads

第一个不太可能-使用MSXML的代码已经过测试和分析,并使用智能指针来控制对象的生存期,因此

The first one is unlikely - the code using MSXML is well tested and analyzed and it uses smart pointers to control objects lifetime, so leaking objects is really unlikely.

第二个看起来不像是可能的原因。我依附于STA,因此不会重复调用这些功能。

The second one doesn't look like the likely reason. I attach to STA and don't call those functions repeatedly.

第三个看起来或多或少的可能性。线程处理消息时,它不再运行消息循环-它已经在循环内部。我想这可能是原因。

The third one looks more or less likely. While the thread is processing the message it doesn't run the message loop anymore - it is inside the loop already. I suppose this might be the reason.

后一个可能是此问题的原因吗?我还应考虑其他哪些原因?我如何轻松解决此问题?

Is the latter a likely reason for this problem? What other reasons should I consider? How do I resolve this problem easily?

推荐答案

不要在线程中做任何后果处理SCM消息时,它处于一种奇怪的魔幻般的环境中-您必须尽快响应SCM的请求,而无需采取任何阻止措施。通过STOP_PENDING告诉您您需要更多时间,将另一个线程排队进行真正的清理,然后立即完成SCM消息。

Don't do anything of consequence in the thread handling SCM messages, it's in a weird magical context - you must answer SCM's requests as fast as possible without taking any blocking action. Tell it you need additional time via STOP_PENDING, queue another thread to do the real cleanup, then immediately complete the SCM message.

对于CoUninitialize,只需附加WinDbg并转储所有线程-死锁很容易诊断(也许无法修复!),您已经有了所有当事方堆积如山的犯罪。

As to the CoUninitialize, just attach WinDbg and dump all the threads - deadlocks are easy to diagnose (maybe not to fix!), you've got all of the parties to the crime right there in the stacks.

这篇关于如何解决挂在CoUnitialize()上的进程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆