COM出站呼叫导致“由于应用程序正在分派输入同步呼叫而不能进行呼出呼叫”。 [英] COM outbound call results in "An outgoing call cannot be made since the application is dispatching an input-synchronous call."

查看:539
本文介绍了COM出站呼叫导致“由于应用程序正在分派输入同步呼叫而不能进行呼出呼叫”。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个COM服务器(C ++ / STA(基于MFC的应用程序))和COM客户端(C#/ MTA)。 COM服务器必须居住在STA,因为它是一个MFC应用程序(我没有选择在这件事)。客户端向服务器发出调用,服务器向客户端发出回调。这是错误发生的地方( RPC_E_CANTCALLOUT_ININPUTSYNCCALL )。我想如果服务器是一个MTA,这个问题永远不会产生,但可悲的是,MFC的文档明确否认将公寓初始化为MTA。

I have a COM server (C++/STA (MFC based app)) and a COM client (C#/MTA). The COM server must live in an STA, since it's an MFC app (I have no choice in this matter). The client issues a call to the server, and the server issues a callback to the client. That's where the error happens (RPC_E_CANTCALLOUT_ININPUTSYNCCALL). I'm guessing if the server had been an MTA, this problem would never have arised, but sadly, the documentation for MFC explicitly denies initializing the apartment as an MTA.

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

Any ideas on how to work around this problem?

我一直在玩的想法让服务器对象(我通过运行的对象表暴露的对象)住在自己的公寓(MTA)。这是一个好主意,还是先有更简单的尝试?

I have been toying with the idea of letting the server object (the object I expose through the running object table) live in an apartment of its own (MTA). Would this be a good idea, or is there something simpler to try first?

UPDATE

服务器对象只是一个瘦接口点,指向应用程序中的某些功能。大多数时候,它只是读取和写入内存位置,但有些情况下,它会生成窗口消息到应用程序中的各个窗口。服务器对象本身不是整个应用程序。

The server object is just a thin interface point to certain functions within the application. Most of the time it just reads and writes to memory locations, but there are instances where it generates window messages to various windows within the application. The server object itself is not the entire application.

推荐答案

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

RPC_E_CANTCALLOUT_ININPUTSYNCCALL means that you attempted to make a marshalled COM call from within the handler for a windows message sent via SendMessage. This is to help avoid certain deadlock situations. You have a number of options, which boil down to "avoid COM calls in a SendMessage handler":


  • 您可以使用 PostMessage 可将消息排队到您自己,并在发布的消息处理程序中调用COM回调。

  • 您可以使用异步DCOM ,并避免在邮件处理程序中对该调用的结果进行阻止。

  • 您可以调用回调接口,然后从线程池工作项。因为这独立于主应用程序的消息循环,所以它不会在SendMessage调用中,甚至可以在MTA中。

  • 您可以放弃MFC COM支持,直接从另一个线程调用 CoRegisterClassObject 。这意味着从COM线程池(或者,如果你使用STA线程,从那个线程)调用你的服务器COM对象的任何调用,从MFC UI线程,不是,所以你会需要使用Windows消息通过线程进行通信;但如果您需要向客户端发出同步调用,这可能是最好的方法。

  • You could use PostMessage to queue up a message to yourself, and in that posted message handler, invoke the COM callback.
  • You could use asynchronous DCOM, and avoid blocking on the result of the call from within the message handler.
  • You could marshal the callback interface, then invoke it from a thread pool work item. Since this is independent from the main application's message loop, it won't be in a SendMessage call, and it could even be in a MTA.
  • You could forgo the MFC COM support, and invoke CoRegisterClassObject directly from another thread. This means any calls into your server COM object will be invoked from the COM thread pool (or, if you use a STA thread, from that thread), not from the MFC UI thread, so you'll need to use Windows messages to communicate across threads; but if you need to make synchronous calls back to the client it may be the best approach.

这篇关于COM出站呼叫导致“由于应用程序正在分派输入同步呼叫而不能进行呼出呼叫”。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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