为什么COM +会忽略公寓线程模型?

时间:2009-05-14 06:41:09

标签: windows com interop com+

我有一个STA COM组件,它被放入COM +应用程序。客户端在该组件中创建该类的多个实例,并且并行调用它们的方法。该类已正确注册 - 相应类ID的“ThreadingModel”为“Apartment”。

我看到在组件内部并行执行相同类的相同方法的几次调用 - 在实际的组件代码中。它们在相同的进程中执行,但是在不同的线程中执行。

发生了什么事? COM +是否忽略了线程模型? STA模型不应该只允许一次执行一个呼叫吗?

4 个答案:

答案 0 :(得分:1)

不,不是真的。 STA的字面意思是“单线程公寓”,这意味着只有一个线程可以在公寓中运行。现在的问题是什么是公寓。公寓是一个过程中的逻辑空间,其实施可能因框架而异。 Microsoft将公寓实现为线程,因为STA(在Microsoft的COM上下文中)转换为单线程线程,即,可以有多个公寓/线程但是在STA的情况下每个公寓/线程将是单线程的。

你可以自己将这个东西概括为MTA。根据我上面所说的,MTA是COM上下文中的多线程线程。

答案 1 :(得分:1)

STA保证只能从一个特定的线程访问您的对象 - 不需要保护共享变量。

我记得对于VB6,有一种特殊模式(我不记得它是如何命名的):你可以允许COM +生成多个STA,每个都使用一个专用对象。但是,这些对象的变量被视为线程本地存储 - 因此,虽然从多个线程访问COM类的多个实例,但不会发生变量共享。你有可能使用这个功能吗?

答案 2 :(得分:1)

您是否将物品传递给住在另一间公寓的物品?如果是这样,你在做之前是否需要编组界面?你碰巧聚合了免费的线程编组吗?

粗略地说,如果将对象的接口传递给另一个公寓(线程)中的对象,则必须确保marshal the interface。如果不这样做,那么您可能会发现您的对象可以从另一个公寓中的对象中自由调用,因为它们不是通过正确处理呼叫的代理进行调用。

  

必须对对象进行所有调用   它的线程(在它的公寓内)。它   被禁止召唤一个物体   直接来自另一个线程;运用   这种自由线程的对象   可能会导致应用程序出现问   这条规则的含义是   所有指向对象的指针必须是   在两者之间传递时被编组   公寓。 COM提供以下内容   为此目的的两个功能:

* CoMarshalInterThreadInterfaceInStream marshals an interface into a stream object that is returned to the caller.
* CoGetInterfaceAndReleaseStream unmarshals an interface pointer from a stream object and releases it.
     

这些函数将调用包装起来   CoMarshalInterface和   CoUnmarshalInterface函数,其中   需要使用MSHCTX_INPROC   标志。

答案 3 :(得分:1)

为避免混淆,我不会在这个答案中使用术语“对象”。相反,让我们使用“类”和“实例”。我相信大家都明白他们之间的区别。

使用ThreadingModel“Apartment”标记您的COM类意味着它的实例将被加载到STA中。创建这些实例的过程将确定它们是进入同一个STA还是进入单独的STA。

正如您所发现的,COM +已将多个实例加载到单独的STA中。

STA获得的保证是多个线程永远不会同时访问单个实例。如果将同一类的单独实例加载到单独的STA中,则它们可以同时由不同的线程访问。

因此,STA实际上是一种保护实例数据的方法。不是你的班级数据。您的COM代码中的任何“共享”或“静态”数据都必须受到您的保护。