为什么我会使用“Both”COM线程模型而不是“Free”?

根据这篇文章,如果我注册我的COM对象与“两个”或“自由”的线程模型,该对象必须是完全线程安全的。 具体来说,所有对全局共享variables的访问都必须同步,并且所有对成员variables的访问也必须同步。 这是很多努力。

现在我明白了,能够注册我的对象为使用“免费”线程模型是有利的,可能值得付出代价,使其完全线程安全。 但为什么我想要做同样的事情,并使用“Both”线程模型来注册我的对象呢? 什么是优势? 我如何select“两者”和“免费”?

线程模型

将组件标记为支持线程模型“Both”的主要原因是从单线程单元(STA)调用组件时的性能改进。

如果您将组件标记为MTA,并且您的组件是从STA内部创建的,那么您的组件将在单独的MTA公寓中创建, “由此产生的公寓间封送可能会降低性能,从而否定所有工作,免费线程组件“ 。 但是,如果你的组件的线程模型被标记为“Both”,那么它将被创建在STA对象的房间内并直接访问。

所以如果你认为你的组件可能是从一个STA中调用的(所有的VB6 COM对象都是STA),你可能要把线程模型标记为“Both”。

关于OLE线程模型的一篇很好的知识库文章。

免费线程模型

如果组件使用标记为“空闲”的其他组件,则可能需要使用“空闲”线程模型。 如果您的组件被标记为“Both”,那么在STA中运行的“Both”组件和MTA之间可能会有过多的公寓切换。 作为一般规则,尽可能在接近呼叫者的地方创建组件(即同一个房间),同时在所有情况下正常运行。

另一种情况下,将组件标记为“自由”是否明确阻止(例如Thread.Sleep)。 如果组件被标记为“Both”并在STA中实例化,则组件将阻塞STA消息泵。

其他考虑和情况

如果您打算在IIS中使用该组件,那么还有其他的事情要考虑。 对于IIS,“Both”是推荐的设置。 主要是为了避免使用Apartment线程组件,对COM + ObjectContext的高性能访问和“自由”线程组件使用系统安全上下文(如果需要访问用户的安全上下文)的事实锁定问题。 有关IIS线程注意事项的更多信息,请参阅选择IIS中组件的线程模型 。

其他要考虑的事情是COM +的支持,以及你的组件如何在COM +中运行以及接口指针是否被传递和存储。

一篇优秀的文章是COM +应用程序中的COM线程和应用程序体系结构 。 它有一个COM +重点,但也讨论COM。 有关您的问题,请阅读标题为“线程模型建议”的部分。 微软已经删除了原来的文章,所以我链接到一个副本。