COM多线程支持多线程、COM

2023-09-03 17:13:56 作者:不戀水de魚

与COM工作首次 我有这个COM DLL,说ABCServer.dll,我创建了一个RCW,并在我的项目添加引用。现在我的应用程序创建多个线程,每个线程COM DLL创建某些类,并适用于他们。但后来每个线程都在等待,而另一个线程从COM DLL正与某一类。

Working with COM for the first time I have got this COM dll, say ABCServer.dll, i created a RCW and added reference to it in my project. Now my application creates several threads and each thread creates certain classes from COM dll and works with them. But then each thread is waiting while other thread is working with certain class from COM dll.

修改我的应用程序的全部目的是使多线程就可以了。现在,多线程是发生在我身边的时候,在COM导致它是连续的。虽然每个线程创建新实例,他们为什么要等着别人来处理?

The whole purpose of modifying my application was enabling multi-threading on it. Now when multithreading is happening at my side, the COM causing it to be sequential. Although each thread is creating new instances, why are they waiting for others to be processed?

推荐答案

有相当的混乱评价和答案为止公布。 STA或MTA是一个线程的一个属性。但重要的是什么COM组件需要。这是在注册表中的ThreadingModel值声明。你找到了公寓,一个很常用的设置。这意味着该组件不支持线程。

There's considerable confusion in the comments and answers posted so far. STA or MTA is a property of a thread. But what matters is what the COM component requires. That's declared in the ThreadingModel registry value. You found "Apartment", a very common setting. It means that the component does not support threading.

这是没有什么不同的类,在.NET框架中的绝大多数,也有极少数是线程安全的。最大的区别是,COM的实施的线程安全的。随着.NET类是由你来写你的code所以类对象在一个线程安全的方式使用。这是很难得到的权利,也是很辛苦慢性源来诊断错误,但精心设计的锁定允许你周围航行的限制。这是不可能的COM,它会永远线程安全,没有你的帮助。即使你想帮助。

This is not unlike the vast majority of classes in the .NET framework, there are very few that are thread-safe. The big difference is that COM enforces threading safety. With .NET classes it is up to you to write your code so the class objects are used in a thread-safe manner. That's difficult to get right and a chronic source of very hard to diagnose bugs but well designed locking allows you to sail around the restrictions. That's not possible with COM, it will always provide thread-safety without you helping. Even if you do want to help.

要获得成功的唯一途径是创建和使用COM组件从只有一个线程。该线程必须Thread.SetApartmentState()来初始化选择STA。其中prevents COM从创建其自己的线程找到一个避风港的组成部分。你必须泵消息循环,一个STA的要求。这可以是痛苦和的也许的回避,如果你不尝试使用COM组件从另一个线程和组件本身不依赖于有一个消息泵使用。这是BTW pretty的常见的。你会注意到它需要之一,当它不再是反应迅速,预计届时通常不会触发一个事件。只有让来自同一个线程COM对象上调用来获得并发与创建自己的对象,其他线程。这不是典型的有用的或可能的。

The only way to get ahead is to create and use the COM component from only one thread. That thread must be initialized with Thread.SetApartmentState() to select STA. Which prevents COM from creating its own thread to find a safe haven for the component. And you must pump a message loop, an STA requirement. Which can be painful and might be avoided if you don't try to use the COM component from another thread and the component itself doesn't depend on having a message pump available. Which is pretty common btw. You'll notice it needs one when it stops being responsive, typically not firing an event when expected. Only make calls on the COM object from the same thread to get concurrency with other threads that create their own object. This is not typically useful or possible.