【问题标题】:The thread associated with the STA of COM object in C#C#中COM对象的STA关联的线程
【发布时间】:2013-10-02 06:16:45
【问题描述】:

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

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

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

非常感谢!

【问题讨论】:

  • 亲爱的投反对票的人,如果你投反对票,请说明原因,否则你的投反对票毫无用处且没有建设性。

标签: c# multithreading com interop


【解决方案1】:

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

当多个客户端调用一个对象时,调用在队列中排队 消息队列和对象每次都会收到一个调用 公寓检索和发送消息。因为电话是 由 COM 同步,并且调用始终由线程传递 属于对象的公寓,对象的接口 实现不需要提供同步,MSDN。

STA 和 MTA

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

CLR 调用 CoInitializeEx

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

【讨论】:

  • 所以每个 COM 对象(在 STA 中)都有一个专门用于执行其功能的线程,比如活动对象?!还是我的线程之一调用“CoInitialize()”并创建了对象?
  • 不,STA中的所有COM对象共享一个线程,即调用CoInitialize()的线程。
【解决方案2】:

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

【讨论】:

  • 请看this related question。我无法确定在调用 Thread.Start 之前是否应该在主线程上调用 CoInitializeEx 或从线程的委托中进行。
猜你喜欢
  • 2020-11-28
  • 1970-01-01
  • 2011-04-13
  • 2011-07-14
  • 1970-01-01
  • 2011-01-11
  • 2011-12-25
  • 2014-02-22
  • 2013-07-28
相关资源
最近更新 更多