将MFC对话框从STA更改为MTA?

时间:2013-09-19 07:05:53

标签: c++ windows multithreading com mfc

我正在开发一个有一些COM接口的API。问题是API通过必须由加载该API的项目实现的接口进行通信。因此,如果我要使用API​​,我会将其加载到我的项目中并创建一个类,该类将实现API调用的方法,以通知我某些事情或将结果传递给我。

这显然会成为一个编组的噩梦。此外,由于还有一些中间对象将调用通过API从不同的插件和管理器传递给实现调用方法的所有对象,这些对象已经将自己注册到API通知程序,因此这一点已经失控了。复杂性。

我在想,为了缩短加载API的人需要完成的工作,如果API遵循免费的线程模型,MFC生成的类(如对话框)是否可以实现通知需要COM接口吗?请记住,这样的对象需要转换为IStream并转换回API端的接口,以便API可以调用这些方法。

据我所知,MFC对话框默认为STA。有没有办法可以强制它们改变或启动MTA? COM的观点是否合法?我试图避免创建另一个对象来处理另一个线程中的通知,因为它会使事情复杂化。此API需要在多个地方使用,有时在GUI中,有时在服务中等等。

1 个答案:

答案 0 :(得分:2)

我理解API本身不仅限于控制线程,您的意图是通过COM接收器接口在后台线程上获取通知。

有三种方法可以解决同时保持COM友好的问题。最简单的是更改应用程序的全局公寓模型,以便将“主”GUI线程初始化为MTA。虽然这可能有效,但您可能很快发现这与其他内容不兼容,例如使用“Arartment”线程模型注册的ActiveX控件。

另一种选择是略微违反COM线程指南,以便API直接从后台线程使用接收器接口而不对其进行编组。这可以正常工作,MFC应用程序准备接收侧线程上的调用,实际上很容易做到(只是在API端的线程/公寓之间自愿传递接收器接口指针)。当.NET客户端使用API​​检测跨公寓接口指针使用时,问题可能会稍后出现。

为了使COM友好并仍然在UI线程上使用STA线程,您可以实现以下方案。 API可以是STA组件,它接受直接传入的接收器接口(由STA中的MFC类实现的COM对象,甚至更简单的东西,如直接在窗口类上实现的COM接口等)。 API编组将接口指针接收到MTA中,以便在工作线程(CoMarshalInterThreadInterfaceInStream和朋友)上使用。 API使用unmarshaled指针从MTA线程传递通知。这通常包括threda切换到您不想要的原始线程,因此为了避免它,MFC端通知类应该实现免费的线程封送器。这将改变一些事情,以便解组的接口指针直接在工作线程上接收调用,MFC应用程序将负责线程同步(关键部分等)。这是STA,COM友好的API工作线程,同时也是高效的。