c# - 对象公寓与线程公寓

标签 c# c++ com atl

我读到了公寓模型,但当我试图理解以下内容时,它仍然让我感到困惑:谁的公寓决定了公寓模型?是线程的套间还是创建对象的套间?
考虑以下场景:

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

  2. 在 C# WinForms 项目中引用此 DLL,并创建 SimpleCom MTA 线程(不是 UI 线程)上的对象。 问题是: 假设 UI 线程调用 test()在这个对象上,它会被编码到创建对象的线程还是在 UI 线程上执行?

    • 如果它遵循对象 COM 单元,则应将此调用编码到创建该对象的线程,因为它是一个 STA 对象。
    • 如果在创建 MTA 线程单元之后,它应该在 UI 线程上执行。

哪一个是正确的?

最佳答案

简单规则:

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

所以一段代码要么在STA(在STA线程上)执行,要么在MTA中执行,要么线程还没有用COM初始化。当您通过 COM 实例化对象时,COM 会将公寓模型与调用 API 的公寓类型相匹配。

This class publicly inherit from CComObjectRootEx which sets STA apartment.

没有。这与设置公寓模型无关。 CComSingleThreadModel 表示此类使用简单的基类,这有利于对象在 STA 上运行 - 特别是在访问对象的引用计数器时它不会使用 InterlockedXxx API 或关键部分,因为类是假设生活在单线程中。这只是设置了COM类的套间模型,并不表示这个类要运行在STA上,只是提供了合适的基类。

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

create the SimpleCom object on a MTA thread (not the UI thread).

... COM 会发现它不能直接在调用线程上实例化,因为该线程属于 MTA。因此 COM 将在工作 STA 线程上实例化,并将创建一个代理/ stub 对以将请求的接口(interface)编码到调用方 MTA 中。

关于c# - 对象公寓与线程公寓,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18977278/

相关文章:

c# - 在 stringbuilder 中查看项目的时间复杂度 - C#

c++ - Bigint +运算符

c++ - 创建服务获取错误 : ERROR_INVALID_ADDRESS (0x000001e7)

c++ - 加载接口(interface)失败

c++ - 从 C++ 中的接口(interface)名称获取 IID? (VS 2010 自动化)

c# - 使用 NCalc 将用户输入评估为字符串中的参数

c# - 图像识别中的K最近邻

c# - 尝试在 C# 中使用 Firebird 客户端创建新的 Firebird 用户时出错

c++ - 二维最近邻搜索移动点

c# - 无法调用 DLL 函数