UI线程阻止调用COM对象的后台线程

时间:2010-04-26 19:59:01

标签: c# multithreading com

我正在开发一个通过第三方COM库与外部设备通信的应用程序。我试图让所有与设备的通信都通过后台线程来防止通信问题搞砸了我的应用程序,并摆脱了在UI线程中进行通信所引入的一些其他复杂性。

问题在于,每当发生导致主UI线程阻塞的事情(即MessageBox.Show被调用或甚至只是在屏幕上移动窗口)时,与后台线程上的设备的通信也会停止。

是否有任何方法(缺少一个完全独立的过程)将两个线程分开足够远以至于它们不会相互干扰? (注意,完全相同的代码与一些数学计算,以减慢一点工作就好了,只有当我使用COM库我才有问题)

2 个答案:

答案 0 :(得分:11)

如果满足以下两个条件,则可以解释您观察到的行为。

  • 第三方COM库旨在在单线程单元中运行
  • 您正在UI线程上的库中创建类的实例

由于UI线程在STA(单线程单元)中运行并且在该线程上创建了COM类,因此对来自除UI线程之外的线程的类的所有调用将被编组到UI线程本身上。如果UI线程被阻止,那么对COM类的所有调用也将被阻塞。

答案 1 :(得分:2)

我想填写Brian的回答。

您是否忘记为工作线程致电TrySetApartmentState(ApartmentState.STA)?如果是这样,我相信您的工作线程默认在MTA中运行,并且所有STA对象都在单独的STA线程(甚至可能是主UI线程)上创建。您应该确保您的工作线程加入STA并查看是否有帮助。

除此之外,COM对象可以注册为主STA。 IIRC,这种情况并不常见。主要STA对象必须存在于主UI线程中。如果这恰好是你的情况,我相信你唯一的选择是求助于工人流程而不是工人线程。