TN064: Model apartment práce s vlákny v ovládacích prvcích ActiveX
Poznámka
Následující technická poznámka se od prvního zahrnutí do online dokumentace neaktualizovala. V důsledku toho můžou být některé postupy a témata zastaralé nebo nesprávné. Nejnovější informace doporučujeme vyhledat v online indexu dokumentace, které vás zajímá.
Tato technická poznámka vysvětluje, jak povolit vlákno modelu bytu v ovládacím prvku technologie ActiveX. Všimněte si, že vlákno modelu apartment-model je podporováno pouze v jazyce Visual C++ verze 4.2 nebo novější.
Co je vlákno modelu apartment-model
Model apartmánu je přístup k podpoře vložených objektů, jako jsou například ovládací prvky technologie ActiveX, v rámci vícevláknové kontejnerové aplikace. I když aplikace může mít více vláken, každá instance vloženého objektu bude přiřazena k jednomu "apartmánu", který se spustí pouze na jednom vlákně. Jinými slovy, všechna volání do instance ovládacího prvku budou probíhat ve stejném vlákně.
Různé instance stejného typu ovládacího prvku však mohou být přiřazeny různým apartmánům. Pokud tedy několik instancí ovládacího prvku sdílí všechna společná data (například statická nebo globální data), bude potřeba přístup k těmto sdíleným datům chránit objektem synchronizace, například kritickým oddílem.
Úplné podrobnosti o modelu vláken bytu naleznete v části Procesy a vlákna v odkazech programátora OLE.
Proč podporovat vlákno modelu apartment-model
Ovládací prvky, které podporují vlákno modelu bytu, lze použít v vícevláknových kontejnerových aplikacích, které podporují také model bytu. Pokud nepovolíte vlákno modelu bytu, omezíte potenciální sadu kontejnerů, ve kterých se dá ovládací prvek použít.
Povolení vláken modelu bytu je pro většinu ovládacích prvků snadné, zejména pokud mají málo nebo žádná sdílená data.
Ochrana sdílených dat
Pokud váš ovládací prvek používá sdílená data, například statickou členovou proměnnou, měl by být přístup k těmto datům chráněn kritickým oddílem, aby se zabránilo úpravám dat ve stejnou dobu více než jedním vláknem. Chcete-li nastavit kritický oddíl pro tento účel, deklarujte statickou členskou proměnnou třídy CCriticalSection
ve třídě vašeho ovládacího prvku. Lock
Použijte funkce a Unlock
členské funkce tohoto kritického objektu oddílu všude, kde váš kód přistupuje ke sdíleným datům.
Představte si například třídu ovládacího prvku, která potřebuje udržovat řetězec sdílený všemi instancemi. Tento řetězec je možné udržovat v proměnné statického členu a chráněný kritickým oddílem. Deklarace třídy ovládacího prvku by obsahovala následující:
class CSampleCtrl : public COleControl
{
...
static CString _strShared;
static CCriticalSection _critSect;
};
Implementace třídy by zahrnovala definice pro tyto proměnné:
int CString CSampleCtrl::_strShared;
CCriticalSection CSampleCtrl::_critSect;
Přístup ke statickému členu _strShared
pak může být chráněný kritickým oddílem:
void CSampleCtrl::SomeMethod()
{
_critSect.Lock();
if (_strShared.Empty())
_strShared = "<text>";
_critSect.Unlock();
...
}
Registrace ovládacího prvku Apartment-Model-Aware
Ovládací prvky, které podporují vlákno modelu apartment-model, by měly indikovat tuto funkci v registru přidáním pojmenované hodnoty ThreadingModel s hodnotou "Apartment" v položce registru ID třídy v klíči třídy\InprocServer32. Pokud chcete, aby byl tento klíč automaticky registrován pro váš ovládací prvek, předejte příznak afxRegApartmentThreading v šestém parametru: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);
}
Pokud byl projekt řízení vygenerován ovládacím programem ControlWizard v jazyce Visual C++ verze 4.1 nebo novější, bude tento příznak již ve vašem kódu. K registraci modelu threadingu nejsou potřeba žádné změny.
Pokud byl projekt generován starší verzí ControlWizard, váš stávající kód bude mít logickou hodnotu jako šestý parametr. Pokud je existující parametr TRUE, změňte ho na afxRegInsertable | afxRegApartmentThreading. Pokud je existující parametr FALSE, změňte ho na afxRegApartmentThreading.
Pokud váš ovládací prvek nevyhovuje pravidlu pro vlákno modelu bytu, nesmíte v tomto parametru předat afxRegApartmentThreading .
Viz také
Technické poznámky podle čísel
Technické poznámky podle kategorií