2011-03-13 27 views
1

我有它創建10個線程+它創建的任務列表中的一個窗口服務。約線程,COM +和STA公寓幾個問題

每個11個線程通過調用CoInitialize(零)進入STA。由一個線程創建

  1. 任務列表中,其他獲得該項目,工藝,並免費....

一)能否其他線程使用由其他線程創建的對象? (那似乎是工作,但..) 二)其他線程釋放由其他線程分配的內存? (那似乎不行...)

我應該以某種方式編組線程之間的指針? 或者我應該至少得到該項目,處理它,但讓它被釋放是創建它的線程的「所有者」?

  1. 在我的Windows服務中,我創建了可用於啓動/停止服務(掛起和恢復線程)的功能。

但是,我有一個實際收集數據的線程的問題,並在間隔中執行它。 當線程加載要處理的項目時,之後它進入睡眠狀態5分鐘。 我怎樣才能安全地終止這樣的線程?如何中止睡眠狀態?

在此先感謝您的幫助!

回答

2

您可能需要跨線程馬歇爾接口。 Here你可以找到一個C++例子,同樣的文章給出了三種方法,您可以使用(oMarshalInterThreadInterfaceInStream/CoMarshalInterface /全局接口表(GIT))。有關它們的更多信息可以在MSDN中找到。

爲了有一個線程等待,但能夠在睡眠結束前終止它,使用WaitForSingleObject的()用適當的超時值和例如Windows事件等待。當函數退出時,它會告訴它是否因爲超時或事件設置而退出。在達到超時之前退出等待功能simnply設置事件。從而可以選擇是否進入另一個等待循環或退出。

+0

從應用實例我讀: 「如果你創建一個STA線程COM對象,您不能接口指針傳遞給另一個STA線程和調出上指針如果你嘗試,你會得到一個錯誤HRESULT 0x8001010E或RPC_E_WRONG_THREAD(應用程序調用這是編組爲一個不同的線程的界面)「。 豈不是隻有COM對象必須編組? 從TObject派生的類的常見實例怎麼樣? – Paul 2011-03-13 12:31:24

+1

這取決於您使用的內容以及如何創建它。與COM相關的一切都必須遵守COM規則。什麼不是在COM控制下沒有。所以,如果你有一個普通的德爾福類實例,你可以通過它和不同的線程使用它,並用「經典」併發技術來保護對它們的訪問。如果你要使用COM對象(也可能是你使用的是,如果你調用CoInitialize),你必須正確地管理它們的接口通過他們線程之間。無論如何,請注意內部包裝COM對象的Delphi類(即與MSXML一起使用時的TXMLDocument) – 2011-03-13 13:12:51

2

要編組STA對象指針在STA線程之間使用CoMarshallInterThreadInterfaceInStreamCoGetInterfaceAndReleaseStream

的STA線程必須抽取消息,因爲這是STA線程如何使用COM,使用Windows消息。即你必須調用GetMessage/TranslateMessage/DispatchMessage。可能你的框架有一個簡單的消息泵功能,你可以用它來做到這一點。

要放棄你的睡眠狀態5分鐘,較短的時間間隔做多睡覺,並檢查「shouldquit」標誌。在Service Main中設置shouldquit標誌。

+0

Ad1。我知道這樣的方法存在,但我很好奇,如果它是兩個線程之間必需的。 Ad2。我知道這是解決方案,但因爲我總是試圖做「等業務」沒有像循環等不necessery處理器cykles,這就是爲什麼我很好奇,如果睡眠或東西可以programically中斷,讓線程優雅地完成了它的工作。 – Paul 2011-03-13 10:34:26

+0

是的,它是兩個線程之間絕對必要的。它將創建一個代理來處理每個調用中的線程/鎖定問題。 另外,STA線程必須抽取消息,所以你無法入睡。你應該做一個消息泵不睡覺。消息泵無論如何都會休眠。 – Ben 2011-03-13 11:26:41

+0

1.爲什麼delphi允許我檢索和使用其他線程創建的對象? 2.所以這是否意味着線程之間傳遞的對象必須來自特定的接口。當它是「解組」(使用CoGetInterfaceAndReleaseStream)時,該對象的實例應該被釋放:在它創建的線程中,還在使用CoGetInterfaceAndReleaseStream的線程中? – Paul 2011-03-13 11:51:54