关闭已创建STA COM对象的线程时,避免断开连接的上下文警告

时间:2011-11-09 15:54:09

标签: .net multithreading com com-interop atl

我正在研究用C ++编写的带有ATL的COM API,客户端将通过它的COM互操作设备在C#中使用。目前,只编写所有COM对象以支持单线程单元模型。

此API的某些功能会导致生成单独的工作线程,从而侦听来自服务器的事件。为响应来自服务器的事件,此工作线程创建一些相当简单的COM对象,然后将这些对象传递给COM事件。 API上还有其他函数会导致API停止侦听来自服务器的事件,然后关闭工作线程。

据我了解,STA的规则是STA COM对象的代码只能在创建它的线程上运行。不幸的是,这似乎导致断开连接的上下文警告,因为.NET COM互操作正在缓存对在此线程上创建的所有COM对象的引用,并且线程在这些引用被释放之前关闭。

我可以看到这个问题的一些潜在解决方案:

  1. 我可以修改我们的COM对象以支持MTA线程模型,因此破坏它们的创建线程不再是一个问题。然而,这可能是一项相当耗时的任务,并且可能使我遇到其他与线程相关的问题。
  2. 我可以添加一些引用计数来保持工作线程活着,直到它的所有COM对象都已被释放。这似乎可能是一种容易出错的方法。
  3. 我可以添加一个全新的线程,该线程旨在永远运行(或者至少在应用程序结束之前)处理COM对象的创建和事件的触发。为此目的使用单个线程可能会产生一些性能瓶颈,但我并不太热衷于此。
  4. 上述所有方法似乎都有其缺点,所以我想知道是否有任何有这些问题处理经验的人有其他方法可以提供?或者,如果有任何优点或缺点,我没有提到上述方法?

1 个答案:

答案 0 :(得分:0)

我最终选择原始问题中的选项1并将每个COM对象切换为在MTA线程模型中运行。所有COM对象都只是一些数据的只读包装器,因此它们已经基本上是线程安全的,切换到MTA只是更新一些.rgs文件和一些CoInitializeEx调用的情况。

对每个人来说,这可能不是一个完美的解决方案,但希望这可以帮助将来遇到这个问题的任何人。