可能有两个相同组件的COM STA实例吗?

时间:2008-11-10 16:38:09

标签: c# multithreading com sta mta

我遇到了问题discovered on another thread here,我需要访问一个STA组件。我将在双核计算机上运行它,使用该组件的进程只能达到CPU的50%。不幸的是,业主表示他们无法将组件更改为MTA,因为该组件是在Matlab编译的混合系统,其核心是C。

所以我尝试在同一进程上加载两个COM类实例,不同的线程访问它,但我不能,只有最后一个COM实例变得可用。你知道什么可以解决这个问题吗?

我正在考虑在同一台计算机上运行我的两个服务进程,以实现100%的cpu。这不是一个好的解决方案,主要是因为这些服务器将安装在我们的基础之外。

3 个答案:

答案 0 :(得分:2)

关于多个STA组件的主题

可以有两个相同STA COM组件的实例,并从C#访问它们。唯一可能阻止你出现这种情况的是对象本身,如果实现为单例对象。

但是,如果两个实例都在同一个STA线程上,则其中一个实例中的活动调用将阻止对该线程的任何其他调用。因此,如果您希望这两个实例并行工作,则需要将它们放在不同的STA线程上。为了安全起见,我将在后台线程上创建两个实例。这应该会阻止您的UI锁定。

关于外部组件的STA与MTA的主题

我不确定为什么C中的组件会阻止它成为MTA对象。成为MTA只意味着对象需要在多个线程之间内部同步它的状态访问和管理代码。

警告:丑陋的黑客攻击! :-)如果您想进行一些实验,可以转到注册表并将外部组件线程模型从Apartment更改为Free,只是为了验证您的代码可以正常使用MTA。但是,他们的组件可能会破坏,因为他们可能没有编写线程安全的代码,依靠COM来保护它们。

在一个突出的位置做一个注释,以便稍后恢复该更改,这样你就不会得到一个他们的代码不起作用的系统,并花了无数个小时追逐鬼魂。 : - )

答案 1 :(得分:0)

Franci Pernov,

我尝试使用两个线程,并在每个线程的上下文中初始化com实例,但错误是相同的:(来自HRESULT的异常:0x80004005(E_FAIL))

我通过CallContext GetData和SetData存储和检索实例。

答案 2 :(得分:-1)

尝试使用相同的DLL注册第二个类。考虑到您可能实际上需要使用不同名称的DLL的单独副本,以便完全安全。

请记住,STA COM类(可能还有它的DLL)不被认为是多线程的线程安全,并且你无法对COM类的外部做任何事情。