c++ - 如何确保无法重入访问我的主 STA COM 服务器 (C++)?

标签 c++ com winapi

好吧,我怀疑我什至很难用语言表达这个,因为我对 COM 和公寓的理解并不能胜任这项工作;-)

我有一个 COM 进程内服务器/组件 (C++),它包装了一些遗留代码。由于此遗留代码的限制,我需要确保 COM 组件的方法是:

  1. 仅在单个线程上调用。
  2. 对于服务器的所有实例,这始终是同一个线程。
  3. (我后来才意识到)没有重入调用。

前两个是我通过使用 ThreadingModel=""注册服务器实现的。

第三个是我什至遇到过的问题。

服务器正被一个我无法控制的多线程客户端使用。它在不同线程上创建服务器/组件的多个实例并调用它们的 DoSomething() 方法。

这会导致选择挂起和崩溃行为,我已经看到堆栈跟踪包含对 DoSomething() 的两次调用,这两个调用都在主 STA 线程上,但针对服务器的不同实例。

起初我什至不认为这是可能的,但我现在有了部分了解,我需要知道是否/如何可以避免这种情况。

我的阅读表明我可能需要以某种方式使用 IMessageFilter,但我不确定这是否可以在服务器端完成,还是需要由客户端完成。

有人可以帮忙吗?

请注意,我正在寻找看看在 COM 级别是否有任何答案,而不是寻求有关更改服务器代码与遗留代码交互方式的建议(例如,通过运行遗留代码在它自己的线程中,并实现我自己的(非 COM)将来自服务器所有实例的调用编码到该线程。

最佳答案

COM 通过消息循环编码对服务器的调用。您可以使用 COM 模态循环进入重入 hell 。该循环负责处理需要编码回客户端线程的传出调用。喜欢事件。或者调用您的服务器对位于不同 STA 单元中的另一台服务器进行调用。当模式循环泵送消息时,等待拨出调用完成,它可以接听来电,就像常规消息循环一样。

从技术上讲,当您的服务器试图通过自己发送消息来保持 UI 事件时,也可能会发生重入。

是的,这可能非常难以处理。我不知道有什么神奇的解决方法,而且我已经努力寻找了很长一段时间。我还查看了 IMessageFilter 并得出结论,它无法解决这个问题。

关于c++ - 如何确保无法重入访问我的主 STA COM 服务器 (C++)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2272715/

相关文章:

c++ - 如何仅通过标准库引用二维数组来使用动态创建的一维数组?

android - 'or' 的目的是 -1 的值?

c++ - 从存储在集合中的数字计算 vector 中的 int?

c# - 从 C# COM 方法返回对象和内存所有权

c++ - 如何制作不依赖 msvc dll 的 win32 应用程序?

c++ - 如何使用 mysql.h 在 C++ 中处理 MySQL NULL?

.Net Com Interop 创建实例缓慢

c++ - _MERGE_PROXYSTUB 有什么意义?

c++ - 使用父窗口的控件打开新窗口

c++ - 将 DriverVersion 转换为人类可读格式