根据this article,如果我使用“Both”或“Free”线程模型注册我的COM对象,该对象必须完全是线程安全的。具体而言,必须同步对全局共享变量的所有访问,并且还必须同步对成员变量的所有访问。这是一项很大的努力。
现在我明白能够将我的对象注册为使用“免费”线程模型是有利的,并且可能值得付出使其完全线程安全的代价。但是为什么我要做所有相同的操作并使用“Both”线程模型注册我的对象呢?有什么好处?如何选择“两者”和“免费”?
答案 0 :(得分:20)
两种线程模型
将组件标记为支持线程模型“Both”的主要原因是在从单线程单元(STA)调用组件时提高性能。
如果您将组件标记为MTA并且您的组件是在STA中创建的,那么您的组件将在单独的MTA公寓和"resultant inter-apartment marshaling might degrade performance enough to negate all the work put into making an efficient, free-threaded component"中创建。但是,如果组件的线程模型标记为“Both”,那么它将在STA对象的单元内创建并直接访问。
因此,如果您认为可以从STA内调用您的组件(所有VB6 COM对象都是STA),您可能希望将线程模型标记为“Both”。
关于OLE Threading Models的好文章。
免费线程模型
如果组件使用标记为“Free”的其他组件,则可能需要使用“Free”线程模型。如果您的组件被标记为“Both”,那么在STA中运行的“Both”组件和MTA之间可能会有过多的公寓切换。作为一般规则,尝试在尽可能靠近调用者(即同一个公寓)的位置创建组件,同时在所有情况下都能正常运行。
另一种可以将组件标记为“Free”的情况是它是否明确阻止(例如Thread.Sleep)。如果组件标记为“Both”并在STA中实例化,则组件将阻止STA消息泵。
其他注意事项和方案
如果您计划在IIS中使用该组件,则还需要考虑其他事项。对于IIS,“Both”是推荐的设置。主要是为了避免公寓线程组件的锁定问题,对COM + ObjectContext的高效访问以及“免费”线程组件使用系统安全上下文(如果您需要访问用户的安全上下文)这一事实。有关IIS线程注意事项的详细信息,请参阅Selecting a Threading Model for Components in IIS。
需要考虑的其他事项是COM +支持以及组件在COM +中运行时的行为以及接口指针是否被传递和存储。
一篇优秀的文章是COM Threading and Application Architecture in COM+ Applications。它有一个COM +焦点,但也讨论COM。有关您的问题,请阅读标题为“线程模型建议”的部分。 Microsoft已删除原始文章,因此我将链接到副本。