【发布时间】:2014-10-31 09:34:46
【问题描述】:
COINIT - 一个用于指定 Windows 线程是在单线程还是多线程单元中的枚举 - 文档 (http://msdn.microsoft.com/en-gb/library/windows/desktop/ms678505(v=vs.85).aspx) 指出:
多线程单元旨在供非 GUI 线程使用。多线程单元中的线程不应执行 UI 操作。这是因为 UI 线程需要消息泵,而 COM 不会为多线程单元中的线程泵送消息。
为什么多线程单元中的线程不应该执行 UI 操作?在多线程单元中的线程中有消息循环有什么问题? COM 是否以某种方式为单线程单元中的线程提供了自动消息循环?
【问题讨论】:
-
您可以创建一个线程,让它加入 MTA,然后在其上运行消息泵;没有什么能阻止你。然而,这通常是没有意义的。如果您在 COM 服务器中执行此操作,并且客户端调用您的 COM 对象上的方法,则此调用将在 不同 MTA 线程(来自 COM 运行时管理的池中的一个)上执行。此外,如果您在此线程上进行公寓外 COM 调用,则该调用将阻塞并且您的 UI 将显示为挂起(而来自 STA 线程的公寓外 COM 调用会在等待调用返回)。
-
是的 - 当 COM 代表您创建 STA 线程时,该线程会运行消息泵。当 MTA 线程创建进程内 STA COM 对象时会发生这种情况。
-
"在多线程单元的线程中存在消息循环有什么问题?"那不是问题。问题是(正如您在引用的文档中所说)“COM 不会为多线程单元中的线程泵送消息”。这意味着如果 COM 需要等待,它将等待而不发送消息,这会挂起您的 UI。 COM 在单线程单元中等待时会发送消息。
-
所以@IgorTandetnik 当您从 STA 线程调用公寓外 COM 对象时,您的正常消息循环(或其他一些消息循环)会在等待时运行吗?如果是后者,这是否记录在任何地方?
-
参见INFO: Descriptions and Workings of OLE Threading Models:“客户端的线程在进行传出呼叫时进入 COM 提供的消息循环。”另见
CoRegisterMessageFilter
标签: c++ windows multithreading com