簡體   English   中英

VB6 GUI 在多線程 COM 環境中不起作用

[英]VB6 GUI not working in multithreaded COM environment

我有一個調用進程內 STA ATL/COM 服務器的 VB6 COM 客戶端。 服務器方法之一,X,可能需要一段時間才能完成,所以我需要能夠取消它。 我嘗試的是在新線程中運行方法代碼並包含另一個方法 Y,它執行定時 WaitForSinleObject。 所以客戶端首先調用 X 然后進入循環調用 VB6 DoEvents 然后 Y 直到 Y 指示 X 已經完成。 這工作正常,但是,美中不足的是 X 線程還通過 IConnectionPoint 接口將事件觸發回客戶端。 事件通過正常,但任何 GUI 調用都不起作用,因為據我所知,GUI 只能在一個線程上工作,即主線程。

使用我現有的代碼有沒有明顯的方法來解決這個問題? 或者,請您建議我可以完成的其他方法。

您應該始終編組您的連接點調用。 當你不這樣做時,你可以調用 VB 代碼,但它以隨機方式失敗(非編組對象),或者只是不起作用(GUI)。

要使用封送處理,您必須實現多個接口(見下文)。

另一種可能性是將對 VB 的異步調用轉換為同步“獲取”調用。

所以你的代碼來自(在C偽代碼中......):

while( !wait( X ) )
{
   doevents();
}

到 :

while( !wait( X ) )
{
    doevents();
    fetch_async_data();
}

1) 通過將編組器添加到 COM_AGGRGATE 表,將編組器添加到您的類中:

CComPtr<IUnknown> m_pUnkMarshaler;

BEGIN_COM_MAP(..)
   ...
   COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
END_COM_MAP()

2) 在 FinalConstruct() 中創建編組器

FinalConstruct()
{
    HRESULT rval = CoCreateFreeThreadedMarshaler( GetControllingUnknown(), &m_pUnkMarshaler.p );
    ...
}

FinalRelease()
{ ...; m_pUnkMarshaler = 0; }

3) 從 IConnectionPointImplMT 派生您的連接點,並在您可以同時觸發多個調用時在內部鎖定調用。

4) 不要在對象的方法中無限期地等待,因為您可能會陷入死鎖。

5) 對每個暴露的對象和連接點重復此操作。

(這應該有效,但我很久沒試過了......)

在 VB6

[英]Using IUnknown derived C++ COM object in VB6

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM