我认为我理解公寓概念以及为什么使用STA或MTA,这是一个问题 到目前为止我找不到任何解决办法。
如果我的应用程序使用引擎盖下的COM对象,例如第三个 派对图书馆,我怎么知道我是否可以使用MultiThreaded-Appartment(MTA)? 在这种情况下,我不知道这些对象是否是线程安全的,所以我需要去 与STA,只是为了安全起见?
答案 0 :(得分:1)
您在STA或MTA线程代码上使用某些COM接口指针的能力取决于您是否所有cab都在此线程上获取此指针。如果你能在STA(或MTA)线程上得到点 - 如果你没有直接将它传递给另一个公寓,你可以进一步使用它。
如果COM服务器以某种方式注册,由于公寓类型不匹配而无法获取指针(典型情况:STA线程和COM服务器使用“免费”公寓模型注册),那么COM将尝试为您编组指针。如果编组成功,你的代码会收到指针,你可以从那里开始。否则你会收到一个错误,你试图从另一个公寓做同样的事情就会成功。基本上,这是获得能够在STA或MTA线程上使用特定COM接口的答案的唯一可靠通用方法。
在实例化COM对象的更具体情况下,您可以查找其注册表信息以查看实例化是否与您的公寓类型匹配。进程外服务器将在任何情况下通过编组为您提供COM接口指针,因此任何客户端公寓都可以使用此服务器。
毫无疑问服务器对象是否是线程安全的。如果他们的COM注册是正确的(特别是STA进程内服务器没有宣布Free / Both注册)并且可以使用编组,则免费提供线程安全性。
答案 1 :(得分:0)
注册的COM对象将属于公寓,根据ThreadingModel字段(another article有关COM公寓的更大,可能更简单的表格。)
基本上,ThreadingModel告诉新创建的对象属于哪个公寓:
未指定
主要STA(第一个CoInitialize
d STA;如果不存在,则COM创建一个,称为主机STA)
公寓
STA(如果我们在STA中,它就是它,否则是主机STA)
免
MTA(如果我们在MTA中,它就是它;否则,COM创建它,称为主机MTA)
两个
现在的公寓是什么
中性
中立公寓
如果您可能正在使用MTA对象,并且您怀疑它们是否是“线程安全的”(这通常意味着它将在每个方法/属性调用上使用实例级别锁定),那么您无法真正做很多事情它。例如,您可以让多个STA同时访问同一个MTA对象。
从中调用并不一定能为您提供此线程的安全性,除非您保证没有其他STA且没有其他人使用相同的对象。
“保证”的作用相反:所有拨打到 STA的呼叫都是顺序的。即便如此,当STA进行公寓间通话时,允许重入呼叫,因此这不是一种类似锁定的保证。
呼叫序列化非常粗糙,因为它位于公寓层面,因此对同一STA的所有呼叫,无论是对象,都将一次执行一个(但可能一个以可重入的方式执行) )。
编辑:可以使用IMessageFilter来控制呼叫重入。