2013-07-03 57 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中調用它。 –