共用方式為


TN064:ActiveX 控制項中的 Apartment Model 執行緒

注意

下列技術提示自其納入線上文件以來,未曾更新。 因此,有些程序和主題可能已過期或不正確。 如需最新資訊,建議您在線上文件索引中搜尋相關的主題。

此技術注意事項說明如何在 ActiveX 控制項中啟用 Apartment 模型執行緒。 請注意,只有 Visual C++ 4.2 版或更新版本才支援 Apartment-model 執行緒。

什麼是 Apartment 模型執行緒

Apartment 模型是支援多執行緒容器應用程式中内嵌物件的方法,例如 ActiveX 控制項。 雖然應用程式可能有多個執行緒,但内嵌物件的每個實例都會指派給一個「Apartment」,這只會在一個執行緒上執行。 換句話說,對 控制項實例的所有呼叫都會在同一個執行緒上發生。

不過,相同類型控制項的不同實例可能會指派給不同的 Apartment。 因此,如果控制項的多個實例共用一般資料(例如靜態或全域資料),則存取此共用資料必須受到同步處理物件的保護,例如重要區段。

如需 Apartment 執行緒模型的完整詳細資料,請參閱 OLE 程式設計人員參考 中的 進程和執行緒

為何支援 Apartment-Model 執行緒

支援 Apartment 模型執行緒的控制項可用於同時支援 Apartment 模型的多執行緒容器應用程式中。 如果您未啟用 Apartment 模型執行緒,將會限制可以使用控制項的潛在容器集。

啟用 Apartment 模型執行緒對於大多數控制項來說很容易,特別是如果它們幾乎沒有或沒有共用的資料。

保護共用資料

如果您的控制項使用共用資料,例如靜態成員變數,該資料的存取應該受到重要區段的保護,以防止一個以上的執行緒同時修改資料。 若要為此設定重要區段,請在控制項的 類別中宣告 類別的靜態成員變數 CCriticalSectionLock無論您的程式碼在何處存取共用資料,請使用這個重要區段物件的 和 Unlock 成員函式。

例如,請考慮需要維護所有實例所共用之字串的控制項類別。 此字串可以在靜態成員變數中維護,並受到重要區段的保護。 控制項的類別宣告會包含下列專案:

class CSampleCtrl : public COleControl
{
...
    static CString _strShared;
    static CCriticalSection _critSect;
};

類別的實作會包含這些變數的定義:

int CString CSampleCtrl::_strShared;
CCriticalSection CSampleCtrl::_critSect;

_strShared然後,可以透過重要區段保護靜態成員的存取:

void CSampleCtrl::SomeMethod()
{
    _critSect.Lock();
if (_strShared.Empty())
    _strShared = "<text>";
    _critSect.Unlock();

...
}

註冊 Apartment-Model-Aware 控制項

支援 Apartment 模型執行緒的控制項應該在登錄中指出這項功能,方法是在類別識別碼 \ InprocServer32 機碼下 ,將具名值 「ThreadingModel」 加上類別識別碼登錄專案中的 「Apartment」 值。 若要讓控制項自動註冊此金鑰,請將第六個參數中的 afxRegApartmentThreading 旗標傳遞 AfxOleRegisterControlClass

BOOL CSampleCtrl::CSampleCtrlFactory::UpdateRegistry(BOOL bRegister)
{
    if (bRegister)
    return AfxOleRegisterControlClass(
    AfxGetInstanceHandle(),
    m_clsid,
    m_lpszProgID,
    IDS_SAMPLE,
    IDB_SAMPLE,
    afxRegApartmentThreading,
    _dwSampleOleMisc,
    _tlid,
    _wVerMajor,
    _wVerMinor);

else
    return AfxOleUnregisterClass(m_clsid,
    m_lpszProgID);

}

如果您的控制項專案是由 Visual C++ 4.1 版或更新版本中的 ControlWizard 所產生,則此旗標已存在於您的程式碼中。 註冊執行緒模型不需要任何變更。

如果您的專案是由舊版 ControlWizard 所產生,則現有的程式碼會有布林值做為第六個參數。 如果現有的參數為 TRUE,請將它變更為 afxRegInsertable | afxRegApartmentThreading 。 如果現有的參數為 FALSE,請將它變更為 afxRegApartmentThreading

如果您的控制項未遵循 Apartment 模型執行緒的規則,您就不得在此參數中傳遞 afxRegApartmentThreading

另請參閱

依編號顯示的技術提示
依分類區分的技術提示