在关闭已创建STA COM对象的线程时避免断开连接的上下文警告 [英] Avoiding disconnected context warning when shutting down a thread on which STA COM objects have been created

查看:252
本文介绍了在关闭已创建STA COM对象的线程时避免断开连接的上下文警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用用ATL编写的C ++编写的COM API,客户端将通过它的COM互操作设施在C#中使用。目前所有的COM对象只能写成支持单线程的公寓模型。

I am working on a COM API written in C++ with ATL, which clients will be expected to use in C# via it's COM interop facilities. Currently all the COM objects are only written to support the single threaded apartment model.

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

Some of the functions of this API cause a separate worker thread to be spawned, which listens for events from a server. In response to events from the server this worker thread creates some fairly simple COM objects, and then passes these objects to a COM event. There are other functions on the API which cause the API to stop listening for events from the server, and then shutdown the worker threads.

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

As I understand it, the rules of STA are that code for an STA COM object will only ever be run on the thread on which it's created. Unfortunately this seems to be causing disconnected context warnings because the .NET COM interop is caching references to all the COM objects that have been created on this thread, and the thread is shutting down before these references are released.

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

I can see a few potential solutions to this problem:


  1. 我可以修改我们的COM对象来支持MTA线程模型,所以其创建线程的销毁不再是一个问题。这可能是一个相当耗时的任务,并且可以打开我其他线程相关的问题。

  2. 我可以添加一些引用计数,以保持工作线程活着,直到它的所有COM对象已经被释放。这似乎可能是一个容易出错的方法。

  3. 我可以添加一个新的线程,旨在永远运行(或至少到应用程序结束),处理创建COM对象和事件触发。有一个单一的线程为这个目的可能会产生一点性能瓶颈,我不太热衷。

上面所有的方法似乎都有他们的缺点,所以我想知道有任何经验的人有处理这些问题有任何其他方法提供吗?或者,如果有任何优点或缺点我没有提到上述方法?

All of the approaches above seem to have their drawbacks, so I was wondering if anyone with experience of dealing with these sort of issues had any other approaches to offer? Or if there are any advantages or drawbacks I haven't mentioned for the above approaches?

推荐答案

我最终选择1在原来的问题和切换每个COM对象过来运行在MTA线程模型。所有的COM对象只是一些数据的只读包装,所以他们已经主要是线程安全的,切换到MTA只是一个更新几个.rgs文件和一些CoInitializeEx调用的情况。

I ended up going for option 1 in the original question and switching each of the COM objects over to run in MTA threading model. All of the COM objects were just read-only wrappers around some data so they were already mostly thread safe and switching to MTA was just a case of updating a few .rgs files and some CoInitializeEx calls.

也许不是每个人的完美解决方案,但希望这有助于任何在未来遇到这个问题的人。

Maybe not the perfect solution for everyone, but hopefully this helps anyone who runs into this problem in the future.

这篇关于在关闭已创建STA COM对象的线程时避免断开连接的上下文警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆