描述:
我的程序既是COM的客户端,又是DDE客户端。当不连接COM服务器时,DDE通信正常;连接COM服务气后,DDE通信的消息全部收不到了。
敬待高手解答。
解决方案1:
由于使用的是COM进程外服务器,楼主的主程序是使用代理来和COM服务器通信的。由于楼主的客户和服务器都是在同一台机子上,所以楼主的主程序中的代理使用的是LPC(本地过程调用)来实现和服务器的通信,而不是RPC(远程过程调用)。
当楼主调用接口的一个函数来传递数据时,调用线程实际调用的是DLL代理中的函数,该函数再通过LPC请求COM服务器调用这个函数,这里就是问题的关键。因为是同步请求(也只能同步),这时调用线程(也就是主程序中的线程)将处于挂起状态,以等待服务器完成请求返回。注意这里只是处于挂起状态,实际线程并没有挂起,而是构建一个模式循环(也就是我前面提到过的模式对话框里所干的事),不停的GetMessage,直到特定的消息(也就是服务器请求完成的通知)到达。如果这时有DDE消息,将会被这个模式循环给滤掉,因此收不到消息。也就是说,在调用COM接口函数前发出的还未处理的DDE消息都将被滤掉,在调用COM接口函数后的则没有问题。
我在MSDN中没有找到有关LPC的资料,所以上面关于LPC等待服务器回答的方式(使用模式循环)只是我个人猜测,不过我认为其有很大的可能性使用模式循环(不使用内核对象来同步),因为使用模式循环(也就是个消息循环)不用切换用户模式和内核模式,可以减少不必要的浪费,并且不用考虑内核对象的释放及传递问题。
如果上面的猜测正确,那么楼主就需要将你的COM服务器改成进程内服务器,即使使用了代理也不会出现上面问题。因为进程内服务器的代码在同一个地址空间下,调用线程可以直接执行。
或者,由于楼主使用的是DDEML,并非DDE,所以可以使用异步Transaction(也就是楼主所说的DDE消息)。MSDN中说使用异步Transaction时,可以同时执行Transactions。言外之意(它没明说,万一不是那就没效了)就是说对于每个Transaction都回生成一个线程以调用相应的回调函数,因此不是基于消息机制的,也就没有上面的问题。
不过我原来从没有编过DDE方面的程序(说实话,回答这帖子之前我都不会DDE),所以上面关于使用异步能否有效我也就不清楚了,只是给楼主提个建议。