Eag*_*arn 5 .net com visual-studio
第一次使用 COM 时, 我得到了这个 COM dll,比如说 ABCServer.dll,我创建了一个 RCW 并在我的项目中添加了对它的引用。现在我的应用程序创建了几个线程,每个线程从 COM dll 创建某些类并使用它们。但是每个线程都在等待,而其他线程正在处理来自 COM dll 的某些类。
修改我的应用程序的全部目的是在其上启用多线程。现在,当我身边发生多线程时,COM 导致它是顺序的。虽然每个线程都在创建新的实例,但它们为什么要等待其他线程被处理?
如果您的 COM 组件被标记为STA(单线程单元),那么您将无法使其成为多线程;该组件的要求是对它的所有调用都被序列化到 STA 所在的线程上,并且 COM 会自动为您处理。
也就是说,如果您的组件是 STA 组件(看起来确实如此)并且您无法将其更改为多线程单元组件 (MTA)或更好的自由线程组件(因此它们之间没有编组)公寓)因为a)它是用VB6编写的,或者b)它是第三方dll,那么你最好使用某种队列模型。
基本上,让你所有的其他工作异步运行,然后有一个线程(或进程,这取决于你),它将尽可能快地一次调用这个组件的请求(请注意,你可以实例化此组件在多个线程中的多个实例,您只需确保ApartmentState将Thread类上的属性设置为ApartmentState.STA),然后在调用完成时发布事件/回调并异步继续其他工作。
它基本上就像有两个生产者/消费者实现,一个将调用分派到 COM 组件,另一个在完成后分派结果。
迄今为止发布的评论和答案存在相当大的混乱。STA 或 MTA 是线程的属性。但重要的是 COM 组件需要什么。这是在 ThreadingModel 注册表值中声明的。您发现了“公寓”,这是一个非常常见的设置。这意味着该组件不支持线程。
这与 .NET 框架中的绝大多数类没有什么不同,只有很少的类是线程安全的。最大的区别是 COM强制执行线程安全。对于 .NET 类,您可以自行编写代码,以便以线程安全的方式使用类对象。这很难做到正确,并且是很难诊断错误的长期根源,但精心设计的锁定可以让您绕过限制。这对于 COM 来说是不可能的,它将始终提供线程安全性,而无需您的帮助。即使你确实想帮忙。
取得成功的唯一方法是仅从一个线程创建和使用 COM 组件。该线程必须使用 Thread.SetApartmentState() 初始化才能选择 STA。这会阻止 COM 创建自己的线程来为组件寻找安全港。并且您必须泵送消息循环,这是 STA 的要求。如果您不尝试从另一个线程使用 COM 组件并且该组件本身不依赖于可用的消息泵,那么这可能会很痛苦,并且可以避免。顺便说一句,这很常见。您会注意到,当它停止响应时,它需要一个,通常不会在预期时触发事件。仅从同一线程调用 COM 对象,才能与创建自己的对象的其他线程实现并发。这通常没有用或不可能。
| 归档时间: |
|
| 查看次数: |
2557 次 |
| 最近记录: |