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

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

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

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

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

最佳答案 我的理解是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工作线程和高效的同时.

点赞