TN064: Apartmentmodellthreading in ActiveX-Steuerelementen

Hinweis

Der folgende technische Hinweis wurde seit dem ersten Erscheinen in der Onlinedokumentation nicht aktualisiert. Daher können einige Verfahren und Themen veraltet oder falsch sein. Um aktuelle Informationen zu erhalten, wird empfohlen, das gewünschte Thema im Index der Onlinedokumentation zu suchen.

In diesem technischen Hinweis wird erläutert, wie Sie das Apartmentmodellthreading in einem ActiveX-Steuerelement aktivieren. Beachten Sie, dass apartmentmodellthreading nur in Visual C++-Versionen 4.2 oder höher unterstützt wird.

Was ist Apartmentmodellthreading?

Das Apartmentmodell ist ein Ansatz zur Unterstützung eingebetteter Objekte, z. B. ActiveX-Steuerelemente, innerhalb einer Multithread-Containeranwendung. Obwohl die Anwendung möglicherweise über mehrere Threads verfügt, wird jeder Instanz eines eingebetteten Objekts ein "Apartment" zugewiesen, das nur für einen Thread ausgeführt wird. Mit anderen Worten, alle Aufrufe in eine Instanz eines Steuerelements erfolgen im selben Thread.

Es können jedoch verschiedene Instanzen desselben Steuerelementtyps verschiedenen Wohnungen zugewiesen werden. Wenn also mehrere Instanzen eines Steuerelements gemeinsame Daten gemeinsam nutzen (z. B. statische oder globale Daten), muss der Zugriff auf diese freigegebenen Daten durch ein Synchronisierungsobjekt geschützt werden, z. B. einen kritischen Abschnitt.

Ausführliche Informationen zum Apartmentthreadingmodell finden Sie unter "Prozesse und Threads " in der OLE-Programmierreferenz.

Gründe für die Unterstützung von Apartmentmodellthreading

Steuerelemente, die Apartmentmodellthreading unterstützen, können in Multithread-Containeranwendungen verwendet werden, die auch das Apartmentmodell unterstützen. Wenn Sie das Apartmentmodellthreading nicht aktivieren, beschränken Sie den potenziellen Satz von Containern, in denen Ihr Steuerelement verwendet werden kann.

Das Aktivieren von Apartmentmodellthreading ist für die meisten Steuerelemente einfach, insbesondere, wenn sie nur wenige oder keine freigegebenen Daten haben.

Schützen freigegebener Daten

Wenn Ihr Steuerelement freigegebene Daten verwendet, z. B. eine statische Membervariable, sollte der Zugriff auf diese Daten durch einen kritischen Abschnitt geschützt werden, um zu verhindern, dass mehrere Threads die Daten gleichzeitig ändern. Um einen kritischen Abschnitt zu diesem Zweck einzurichten, deklarieren Sie eine statische Membervariable der Klasse CCriticalSection in der Klasse Ihres Steuerelements. Verwenden Sie die Lock Funktionen und Unlock Member dieses kritischen Abschnittsobjekts, unabhängig davon, wo Ihr Code auf die freigegebenen Daten zugreift.

Betrachten Sie beispielsweise eine Steuerelementklasse, die eine von allen Instanzen gemeinsam genutzte Zeichenfolge Standard muss. Diese Zeichenfolge kann in einer statischen Membervariable Standard und durch einen kritischen Abschnitt geschützt werden. Die Klassendeklaration des Steuerelements würde Folgendes enthalten:

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

Die Implementierung für die Klasse würde Definitionen für diese Variablen enthalten:

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

Der Zugriff auf das _strShared statische Element kann dann durch den kritischen Abschnitt geschützt werden:

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

...
}

Registrieren eines Apartmentmodell-fähigen Steuerelements

Steuerelemente, die apartmentmodellthreading unterstützen, sollten diese Funktion in der Registrierung angeben, indem der benannte Wert "ThreadingModel" mit dem Wert "Apartment" in ihrem Klassen-ID-Registrierungseintrag unter der Klassen-ID32-Schlüssel\ hinzugefügt wird. Damit dieser Schlüssel automatisch für Ihr Steuerelement registriert wird, übergeben Sie das afxRegApartmentThreading-Flag im sechsten Parameter an 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);

}

Wenn Ihr Steuerelementprojekt von ControlWizard in Visual C++ Version 4.1 oder höher generiert wurde, ist dieses Flag bereits im Code vorhanden. Zum Registrieren des Threadingmodells sind keine Änderungen erforderlich.

Wenn Ihr Projekt von einer früheren Version von ControlWizard generiert wurde, weist Ihr vorhandener Code einen booleschen Wert als sechsten Parameter auf. Wenn der vorhandene Parameter WAHR ist, ändern Sie ihn in afxRegInsertable | afxRegApartmentThreading. Wenn der vorhandene Parameter FALSE ist, ändern Sie ihn in afxRegApartmentThreading.

Wenn Ihr Steuerelement nicht den Regeln für Apartmentmodellthreading entspricht, dürfen Sie in diesem Parameter keine afxRegApartmentThreading übergeben.

Siehe auch

Technische Hinweise – nach Nummern geordnet
Technische Hinweise – nach Kategorien geordnet