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

标签 c++ windows multithreading com mfc

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

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

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

据我所知,MFC 对话框默认是 STA。有什么方法可以强制他们更改或开始使用 MTA?从 COM 的角度来看,它是否合法?我试图避免创建另一个对象来处理另一个线程中的通知,因为这会使事情复杂化。此 API 需要在多个地方使用,有时在 GUI 中,有时在服务中等。

最佳答案

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

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

另一种选择是稍微违反 COM 线程准则,这样 API 就可以直接从后台线程使用接收器接口(interface),而无需对其进行编码(marshal)处理。这将与准备好接收侧线程调用的 MFC 应用程序一起正常工作,并且实际上很容易做到(只需在 API 侧的线程/单元之间自愿传递接收器接口(interface)指针)。当检测跨单元接口(interface)指针使用的 .NET 客户端使用 API 时,稍后可能会出现此问题。

为了使其对 COM 友好并且在 UI 线程上仍然使用 STA 线程,您可以实现以下方案。 API可以是接受直接传入sink接口(interface)的STA组件(STA中MFC类实现的COM对象,或者更简单的如直接在window类上实现的COM接口(interface)等)。 API 编码将接口(interface)指针汇入 MTA 以供工作线程使用(CoMarshalInterThreadInterfaceInStream 和 friend )。 API 使用未编码的指针从 MTA 线程传递通知。这通常包括 threda 切换到您不想要的原始线程,因此为了避免它,MFC 端通知类应该实现自由线程编码(marshal)拆收器。这将改变一些事情,以便未编码的接口(interface)指针直接在工作线程上接收调用,而 MFC 应用程序将负责线程同步(关键部分等)。这是 STA、COM 友好的 API 工作线程,同时高效。

关于c++ - 将 MFC 对话框从 STA 更改为 MTA?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18888243/

相关文章:

c++ - 使用数组作为计数器的输出不正确

windows - WaitForMultipleObjects() 是否重置所有自动重置事件?

windows - 在批处理文件中使用目录名更改文件名

java - Aerospike 中 batchRequests 的低性能

c++ - 数字与数字数组的差之和

c++ - 如何通过子类型列表创建指针 vector ?

python - 如何将大部分原始文件系统复制到文件中?

java - Weblogic Server 11g 上的自定义线程

java - 如何使 Java Spring 组件类线程安全?

c++ - 如何消除这种与继承相关的代码异味?