2013-07-03 56 views
0

我有一个线程A(主STA线程),它创建一个COM对象,并且想将它传递给另一个线程,所以我使用了CoMarshalInterface API。CoReleaseMarshalData usage

线程B(MTA/STA无关紧要)处理许多类型的事件,其中一个事件接收数据流并调用CoUnmarshalInterface来获取代理对象。

因为调用CoUnmarshalInterface可能失败(因为任何原因),如果真的发生了,我必须调用CoReleaseMarshalData释放流数据,但是,MSDN文档说:

重要:你必须调用CoReleaseMarshalData功能在同一个 公寓,称CoMarshalInterface将对象编组为 这个流。如果不这样做,可能会导致流中封送的数据包被泄漏,导致 所持有的对象引用被泄漏。

所以,在线程A,我实现了一个等待的CoMarshalInterface调用后,检查是否CoUnmarshalInterface成功与否,但问题是,虽然我等待,如果线程B或另一个人让远程-COM操作,因为线程A被阻塞等待结果,我得到一个死锁。

我也尝试使用CoWaitForMultipleHandles没有运气。

真的需要在同一间公寓拨打CoReleaseMarshalData吗?你知道处理这个问题的另一种方法吗?

回答

0

你的问题似乎并没有与编组本身有关。是的,你做CoUnmarshalInterface从您建立的公寓释放编组流,但问题似乎是线程间的同步,而不是编组本身:

所以,在线程A,我实现了一个等待的CoMarshalInterface后调用并检查CoUnmarshalInterface是否成功,但问题是,在我等待的时候,如果线程B或另一个线程执行remote-com操作,因为线程A被阻塞等待结果,则会导致死锁。

当你手中有流,并将呼叫发送到另一个公寓时,重要的是你如何等待。由于您在STA中,因此您仍应在等待时(例如使用MsgWaitForMultipleObjectsEx)在线程上发送窗口消息。相反,你认为这个区块是短期的,可以等待一段时间。那么如果在线程A上有一个依靠消息分派的后向调用 - 这就是死锁进入的地方。

所以问题首先是阻塞STA线程,包括阻塞消息分派。等待发送邮件,或将流放到安全的地方供以后发布时,您不必急于使用CoUnmarshalInterface那么多,您可以稍后在第一次方便时释放资源。

+0

嗨@Roman,我用'CoWaitForMultipleHandles'做了等待,但结果是一样的。我可以删除等待,让程序继续执行。线程B将接收流并调用'CoUnmarshalInterface',但是如果解组失败,我可以安全地调用线程B中的'CoReleaseMarshalData',还是应该使用QueueUserAPC定位线程A释放编组数据?基本上我遇到的问题是发布数据,而不是解组数据。 –

+0

当然,你可以拥有一个标志(或者流的存在本身就是这样一个指标),一旦'CoUnmarshalInterface'成功,你不再需要在线程A上调用'CoReleaseMarshalData'。 –

+0

是的,但是我的问题是在哪里调用' CoReleaseMarshalData'如果解组失败。在线程A中排队用户apc或者我可以在线程B中调用它。 –