如何确保对我的主 STA COM 服务器 (C++) 没有可重入访问? [英] How do I ensure no re-entrant access to my main-STA COM server (C++)?

查看:27
本文介绍了如何确保对我的主 STA COM 服务器 (C++) 没有可重入访问?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

OK, I suspect I'm going to have difficulty even putting this in words since my understanding of COM and apartments isn't really up to the job ;-)

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

I have a COM in-process server/component (C++) that wraps some legacy code. Due to the limitations of this legacy code I need to ensure that the methods of the COM component are:

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

前两个我通过使用 ThreadingModel="" 注册服务器来实现.

The first two I achieved by registering the server with ThreadingModel="".

第三个是我什至惊讶地遇到的问题.

The 3rd is a problem I was suprised to even encounter.

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

The server is being used by a multi-threaded client which I have no control over. It is creating multiple instances of the server/component on different threads and calling their DoSomething() method.

这导致了一系列挂起和崩溃行为,我看到堆栈跟踪包含两个在主 STA 线程上对 DoSomething() 的调用,但针对不同的服务器实例.

This is leading to a selection of hanging and crashing behaviour and I have seen stack traces containing two calls to DoSomething() both on the main-STA thread, but for different instances of the server.

一开始我什至不认为这是可能的,但我现在有了部分理解,我需要知道是否/如何预防.

I initially didn't even think this was possible, but I now have a partial understanding and I need to know if/how it can be prevented.

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

My reading suggests that I may need to use IMessageFilter in some fashion, but I'm not sure if this is something that can be done on the server side, or needs to be done by the client.

有人可以帮忙吗?

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

Please note I am looking to see if there are any answers at the COM level, rather than looking for suggestions about changing the way that the server code interacts with the legacy code (e.g. by running the legacy code in its own thread and implementing my own (non-COM) marshalling of the calls from all instances of the server onto that thread).

推荐答案

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

COM marshals calls to your server through the message loop. You can get into re-entrancy hell with the COM modal loop. That loop takes care of outgoing calls that need to be marshaled back to the client thread. Like events. Or calls your server makes to another server that's in a different STA apartment. While the modal loop pumps messages, waiting for the outgoing call to be completed, it can pick up incoming calls, just like the regular message loop.

从技术上讲,当您的服务器试图通过自身泵送消息来保持 UI 活动时,也可能发生重入.

Technically, re-entrancy can also happen when your server is trying to keep a UI alive by pumping messages itself.

是的,这可能非常难以处理.我不知道有什么神奇的解决方法,而且我已经努力寻找了一段时间.我也看了IMessageFilter,结论是解决这个问题没用.

Yes, this can be very hard to deal with. I'm not aware of any magic fix for this, and I've been looking hard for quite a while. I also looked at IMessageFilter and concluded it was useless to solve this problem.

这篇关于如何确保对我的主 STA COM 服务器 (C++) 没有可重入访问?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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