COM出站呼叫导致"由于应用程序正在调度输入同步呼叫,因此无法进行拨出呼叫."

Jör*_*son 10 com mta sta visual-c++

我有一个COM服务器(C++/STA(基于MFC的应用程序))和一个COM客户端(C#/ MTA).COM服务器必须位于STA中,因为它是一个MFC应用程序(在这个问题上我别无选择).客户端向服务器发出调用,服务器向客户端发出回调.这就是错误发生的地方(RPC_E_CANTCALLOUT_ININPUTSYNCCALL).我猜测服务器是否是MTA,这个问题永远不会出现,但遗憾的是,MFC的文档明确否认将公寓初始化为MTA.

关于如何解决这个问题的任何想法?

我一直在想让服务器对象(我通过运行对象表公开的对象)住在自己的公寓(MTA)中.这是一个好主意,还是先尝试一些简单的东西?

UPDATE

服务器对象只是指向应用程序中某些功能的精简界面.大多数情况下,它只是读取和写入内存位置,但有些情况下它会向应用程序中的各个窗口生成窗口消息.服务器对象本身不是整个应用程序.

bdo*_*lan 12

RPC_E_CANTCALLOUT_ININPUTSYNCCALL表示您尝试从处理程序内为通过发送的Windows消息进行编组的COM调用SendMessage.这有助于避免某些死锁情况.您有许多选项,可以归结为"避免在SendMessage处理程序中调用COM":

  • 您可以使用PostMessage将消息排队给自己,并在该发布的消息处理程序中调用COM回调.
  • 您可以使用异步DCOM,并避免阻止来自消息处理程序的调用结果.
  • 您可以封送回调接口,然后从线程池工作项调用它.由于这与主应用程序的消息循环无关,因此它不会在SendMessage调用中,甚至可能在MTA中.
  • 您可以放弃MFC COM支持,并直接从另一个线程调用CoRegisterClassObject.这意味着将从COM线程池(或者,如果您使用STA线程,从该线程)调用对服务器COM对象的任何调用,而不是从MFC UI线程调用,因此您将需要使用Windows消息进行通信跨线程; 但如果您需要将同步呼叫发回客户端,则可能是最佳方法.