我有一个STA COM组件,它被放入COM +应用程序。客户端在该组件中创建该类的多个实例,并且并行调用它们的方法。该类已正确注册 - 相应类ID的“ThreadingModel”为“Apartment”。
我看到在组件内部并行执行相同类的相同方法的几次调用 - 在实际的组件代码中。它们在相同的进程中执行,但是在不同的线程中执行。
发生了什么事? COM +是否忽略了线程模型? STA模型不应该只允许一次执行一个呼叫吗?
答案 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代码中的任何“共享”或“静态”数据都必须受到您的保护。