为什么不应该在multithreading的公寓住?

COINIT – 用于指定Windows线程是单线程还是multithreading单元的枚举 – 文档( http://msdn.microsoft.com/zh-cn/library/windows/desktop/ms678505(v=vs.85) .aspx )指出:

multithreading单元旨在供非GUI线程使用。 multithreading套件中的线程不应该执行UI操作。 这是因为UI线程需要消息泵,并且COM不会为multithreading公寓中的线程抽取消息。

为什么multithreading套件中的线程不应该执行UI操作? 在multithreading公寓的线程中发生消息循环有什么问题? COM以某种方式为单线程单元中的线程提供自动消息循环?

这有点倒退,一个UI线程主要需要一个消息循环,以便它可以接收来自Windows和其他进程的通知。 消息循环是生产者 – 消费者问题的通用解决方案。 随着操作系统和其他进程的产生,UI线程消耗。

一个UI线程使用了大量的非线程安全的代码。 这包括COM中实现的主要功能,如拖放,剪贴板,外壳对话框,ActiveX控件(如浏览器)。 还有一堆从来没有做过线程安全的代码,因为程序员不需要这么做,写起来更容易。 这些功能需要一个STA线程,换句话说,就是一个通过将COINIT_APARTMENTTHREADED传递给CoInitializeEx()来初始化COM的线程。

这是对COM的承诺 ,线程将是一个好公民,不允许进行阻塞呼叫,并且必须抽取消息循环。 这是COM用于将工作线程调用编组到STA线程的消息循环,以保持COM对象线程安全。 当所有的电话都是由同一个线程完成的,那么就没有安全问题。 底层的调用是SendMessage(),用大量的管道将函数参数从一个栈复制到另一个栈。 CoInitializeEx()创建一个隐藏的消息窗口,由处理消息的STA线程拥有,并实际进行呼叫。 安全。