共用方式為


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

注意事項注意事項

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

這個技術提示說明如何啟用 ActiveX 控制項的 Apartment Model 執行緒。 請注意 Apartment Model 執行緒在 Visual C++ 4.2 版 (含) 以後版本才支援。

什麼是 Apartment Model 執行緒?

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

不過,同一個控制項的不同執行個體可以指派給不同的 Apartment。 對這個的,因此,如果控制項的多個執行個體共用任何資料共同的 (例如,靜態或全域資料),然後存取共用資料必須受同步物件的保護,例如關鍵區段。

如需在 Apartment 執行緒模型的完整詳細資訊,請參閱《 OLE 程式設計人員參考》的處理序和執行緒

為什麼支援 Apartment Model 執行緒?

支援 Apartment Model 執行緒的控制項也支援 Apartment 模型的多執行緒的容器應用程式。 如果不啟用 Apartment Model 執行緒,您可能會限制您的控制項可以使用的設定容器。

特別是如果它們有少許或不使用共用資料,啟用 Apartment Model 執行緒對大部分控制項都可以。

保護共用資料

如果您的控制項共用資料,例如靜態成員變數,請存取該應該保護資料以關鍵區段防止多個執行緒同時修改資料。 若要針對此目的設定關鍵區段,請宣告類別 CCriticalSection 的靜態成員變數在您的控制項的類別。 使用這個關鍵區段物件的 Lock 和 Unlock 成員函式的地方,您的程式碼存取共用資料。

考量,例如,需要保留字串的所有執行個體共用的控制項類別。 這個字串使用靜態成員變數可以維護和受關鍵區段 (Critical Section) 保護。 控制項的類別宣告中包含下列項目:

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 明確的控制項

支援 Apartment Model 執行緒的控制項應該將具名值表示註冊這個功能, 「ThreadingModel」與「Apartment」值在其類別 ID 登錄項目在 類別 ID\InprocServer32 機碼。 若要讓這個金鑰便會自動註冊控制項,請將第六個參數的 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 Model 執行緒的規則,您不能將這個參數的 afxRegApartmentThreading 。

請參閱

其他資源

依編號顯示的技術提示

依分類區分的技術提示