0

在 C++ 中,当我调用 CoInitialize() 时,正在创建一个与调用“CoInitialize()”的线程 t 相关联的 STA。现在,如果我理解正确的话,当 t 创建一个 COM 对象时,该对象与与 t 关联的 STA 相关联,这意味着只有“t”可以调用该对象。

我的问题是 C# 中发生了什么?谁调用 CoInitialize()?

一些背景:我的问题来自线程模拟问题。一个线程被模拟给用户,然后它调用 COM 对象,调用 COM 对象的线程是否真的是执行内部代码的线程(在 COM 对象内部没有新线程)。

非常感谢!

4

2 回答 2

2

COM 对象是单线程的,不能有多个线程。STA 负责 COM 组件的多个使用者的同步。

当多个客户端调用一个对象时,这些调用会在消息队列中排队,并且该对象每次在其单元检索和调度消息时都会收到一个调用。因为调用是由 COM 同步的,并且调用总是由属于对象单元的线程传递,所以对象的接口实现不需要提供同步,MSDN

STA 和 MTA

为了互操作性,公共语言运行库在调用 COM 对象时创建并初始化一个单元。托管线程可以创建并进入仅包含一个线程的单线程单元 (STA) 或包含一个或多个线程的多线程单元 (MTA)。当 COM 单元和线程生成的单元兼容时,COM 允许调用线程直接调用 COM 对象。如果公寓不兼容,COM 创建一个兼容的公寓并通过新公寓中的代理编组所有调用,参考

CLR 调用 CoInitializeEx

运行时调用 CoInitializeEx 将 COM 单元初始化为 MTA 或 STA 单元。在 .NET Framework 2.0 版中,如果托管线程在启动线程之前尚未设置其单元状态,则将其初始化为 MTA。在启动线程之前使用SetApartmentState或TrySetApartmentState方法设置公寓状态,参考;

于 2013-10-02T06:22:41.053 回答
0

为了进一步回答您的问题,在 C# 中,CLRCoInitialize代表您调用。您可以使用方法上的[STAThread]属性main或设置线程的ApartmentState 属性来设置线程模型。

于 2013-10-02T17:07:53.547 回答