对象公寓vs螺纹公寓

时间:2013-09-24 09:08:58

标签: c# c++ com atl

我读到了关于公寓模型的信息,但是当我试图理解以下内容时,我仍然感到困惑:他的公寓决定了公寓模型?是线程的公寓还是创建对象的公寓? 请考虑以下情形:

  1. 我创建了只有一个ISimpleCom接口的C ++ ATL COM dll,我有一个类只有一个方法test();的接口类 该类公开继承自设置STA公寓的CComObjectRootEx<CComSingleThreadModel>

  2. 在C#WinForms项目中引用此DLL,并在MTA线程(而不是UI线程)上创建SimpleCom对象。 问题是: 让我们说这个对象上的UI线程调用test(),它是否会被编组到创建该对象的线程中,或者它将在UI线程上执行?

    • 如果它跟随对象COM公寓,则应该将该调用封送到创建该对象的线程,因为它是一个STA对象。
    • 如果它跟随创建MTA的线程公寓,它应该在UI线程上执行。
  3. 哪一个是正确的?

1 个答案:

答案 0 :(得分:2)

简单的规则:

  • 一个帖子可能是零或一个公寓的成员
  • 单线程单元(STA)由一个或多个线程的单线程MTA组成,但每个进程最多只能有一个MTA
  • 线程在COM初始化时“加入”公寓

因此,一段代码在STA(在STA线程上)或在MTA中执行,或者该线程尚未使用COM初始化。当您通过COM实例化对象时,COM会将公寓模型与调用API的公寓类型相匹配。

  

此类公开继承自设置STA公寓的CComObjectRootEx。

没有。这与设置公寓模型无关。 CComSingleThreadModel说这个类使用的是简单的base,这对于在STA上运行的对象很有用 - 特别是在访问对象的引用计数器时它不会使用InterlockedXxx API或关键部分,因为该类被认为是活的在单线程内。这确实设置了COM类的公寓模型,它并不表示该类是在STA上运行的,这只是提供了合适的基类。

ATL COM DLL托管类的公寓模型将在.RGS文件上显示,与COM类关联,并将与DLL注册合并到注册表中。如果这是“公寓”型号那么......

  

在MTA线程(而不是UI线程)上创建SimpleCom对象。

... COM会看到它无法直接在调用线程上实例化,因为该线程属于MTA。因此,COM将在工作者STA线程上实例化,并将创建一个代理/存根对,以将请求的接口称为调用者MTA。