间接使用的COM对象的STA或MTA

间接使用的COM对象的STA或MTA,com,sta,mta,Com,Sta,Mta,我想我理解公寓的概念以及为什么使用STA或MTA,但这是一个问题 到目前为止我还没有找到解决办法 如果我的应用程序在引擎盖下使用COM对象,例如从第三个 党的图书馆,我怎么知道我是否可以使用多线程装置(MTA)? 在这种情况下,我不知道这些对象是否是线程安全的,所以我需要去吗 对于STA,为了安全起见?您是否能够在STA或MTA线程代码上使用某些COM接口指针取决于您是否在该线程上获取该指针。如果您可以在STA(或MTA)线程上获得该点,那么您最好进一步使用它,前提是您不直接将其传递到其他单元

我想我理解公寓的概念以及为什么使用STA或MTA,但这是一个问题 到目前为止我还没有找到解决办法

如果我的应用程序在引擎盖下使用COM对象,例如从第三个 党的图书馆,我怎么知道我是否可以使用多线程装置(MTA)? 在这种情况下,我不知道这些对象是否是线程安全的,所以我需要去吗
对于STA,为了安全起见?

您是否能够在STA或MTA线程代码上使用某些COM接口指针取决于您是否在该线程上获取该指针。如果您可以在STA(或MTA)线程上获得该点,那么您最好进一步使用它,前提是您不直接将其传递到其他单元

如果COM服务器以某种方式注册,由于单元类型不匹配而无法获取指针(典型情况:STA线程和COM服务器使用“免费”单元模型注册),则COM将尝试为您封送指针。如果封送成功,您的代码将收到指针,您可以从那里开始。否则,您将得到一个错误,并且您尝试从另一个单元执行相同的操作将成功。基本上,这是唯一可靠的通用方法来获得能够在STA或MTA线程上使用特定COM接口的答案

在实例化COM对象的更具体的情况下,您可以查找其注册表信息,查看实例化是否与公寓类型匹配。进程外服务器将在任何情况下通过封送为您提供COM接口指针,因此任何客户端单元都将能够使用此服务器


毫无疑问,服务器对象是否是线程安全的。如果COM注册正确(特别是proc server中的STA没有宣布免费/同时注册),并且封送可用,则线程安全性将免费提供。

根据字段,注册的COM对象将属于一个单元(大约有一个更大、可能更简单的表的COM单元)

基本上,ThreadingModel告诉您新创建的对象将属于哪个单元:

  • 未指定

    主STA(第一个
    CoInitialize
    d STA;如果不存在,COM将创建一个称为主机STA的STA)

  • 公寓

    STA(如果我们在STA中,则为它,否则为主机STA)

  • 免费的

    MTA(如果我们在MTA中,它将是它;否则,COM将创建它,称为主机MTA)

  • 两者

    现在的公寓是什么

  • 中立的

    中立公寓

如果您可能正在使用MTA对象,并且怀疑它们是否是“线程安全的”(这通常意味着它将在每个方法/属性调用上使用实例级锁),那么您实际上对此无能为力。例如,可以让多个STA同时访问同一MTA对象

从STA调用不一定能保证线程安全,除非您保证没有其他STA,也没有其他人在使用相同的对象

“保证”的作用是相反的:对STA的所有呼叫都是连续的。即便如此,在STA进行公寓间呼叫时,允许重入呼叫,因此这并不是真正的锁式保证

调用序列化非常粗糙,因为它位于单元级别,所以对同一STA的所有调用,无论对象是什么,都将一次执行一个(但可能以重入方式一个接一个地执行)



编辑:呼叫重新进入可以通过控制。

谢谢!我不明白每一点,因为我不深入COM相关的东西。我根本没有使用任何COM对象,但有些代码似乎在幕后使用COM。例如,我得到了一个阻塞的终结器,因为vb.net使用STA作为默认值,消息循环被thread.Sleep阻塞。我想确保,我可以安全地切换到MTA(这是c#中的默认设置),之后就不再关心它了。但经过大量调查,我仍然不确定这是否会以某种方式破坏我的代码!?COM的规则是不在单元之间直接传递指针(这通常意味着在STA线程中,不能在该线程之外传递指针,并且可以在MTA线程之间传递指针,但不能在STA线程之外传递)。在处理VB.NET代码中的COM接口时,需要记住这一点。NET运行时会进行额外的检查,并防止指针被误用,所以任何一步都可能导致异常。