TN064: 公寓模型執行緒 ActiveX 控制項中
![]() |
---|
由於它第一次線上文件中包含尚未更新下列技術提示。如此一來,某些程序和主題可能已經過期或不正確。如需最新資訊,建議您先搜尋線上文件索引中有興趣的主題。 |
這份技術提示會說明如何啟用 [公寓模型執行緒處理 ActiveX 控制項中。請注意公寓模型執行緒只支援在 Visual C++ 4.2 (含) 以後的版本。
公寓模型執行緒是什麼?
公寓模型是一個支援內嵌的物件,例如 ActiveX 控制項,在多執行緒的容器應用程式中的方法。雖然應用程式可能會有多個執行緒時,內嵌物件的每個執行個體將會指派給一個"公寓,"這將在只有一個執行緒上執行。亦即,控制項的執行個體的所有呼叫就會都發生在相同執行緒上。
不過,相同的控制項類型的不同執行個體可能會指派給不同公寓。因此,如果控制項的多個執行個體共用一般 (比方說,靜態或全域資料) 中的任何資料,然後存取此共用的資料必須受保護的同步物件,例如重要區段。
如 apartment 執行緒模型的詳細資訊,請參閱處理序和執行緒 在 OLE 程式設計人員參考。
為什麼支援公寓模型執行緒嗎?
支援 [公寓模型執行緒控制項可用在多執行緒的容器應用程式也支援 [公寓模型。如果您未啟用公寓模型執行緒處理,您可限制可能無法使用您的控制項的容器的集合。
啟用 [公寓模型執行緒很簡單大部分的控制項,特別是當它們有幾乎沒有任何共用的資料。
保護共用資料
如果您的控制項使用的共用的資料,例如靜態成員變數,存取資料都必須使用關鍵區段以防止多個執行緒同時修改的資料加以保護。若要設定的重要區段,為上述目的,來宣告類別的靜態成員變數CCriticalSection控制項的類別中。使用Lock和解除鎖定成員函式的這個關鍵區段物件的任何程式碼存取共用的資料的位置。
例如,考慮控制項類別,便需要維護共用的所有例項的字串。這個字串可以保存在靜態成員變數,並受關鍵區段。控制項的類別宣告可以包含下列各項:
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();
...
}
正在註冊公寓模型感知的控制項
公寓模型執行緒所支援的控制項應該在登錄中,這項功能新增顯示已命名的值"ThreadingModel"下其類別識別碼登錄項目中,值為"公寓" 類別識別碼\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。
如果您的控制項未遵守的規則公寓模型執行緒處理時,您必須將afxRegApartmentThreading這個參數中。