Ein Threading-Modell auswählen

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Den Automatisierungsobjekt-Experten verwenden


Beim expertengestützten Erstellen eines Objekts wählen Sie ein Threading-Modell aus, das von Ihrem Objekt unterstützt wird. Durch Hinzufügen von Threading-Unterstützung zu COM-Objekten können Sie deren Leistungsfähigkeit erhöhen, da mehrere Clients auf die Anwendung gleichzeitig zugreifen können.

In der folgenden Tabelle sind die verschiedenen verfügbaren Threading-Modelle aufgelistet.

Threading-Modelle für COM-Objekte:

Threading-Modell Beschreibung Vor- und Nachteile

Single

Keine Threading-Unterstützung durch den Server. COM serialisiert Client-Anforderungen, so dass die Anwendung jeweils eine Anforderung erhält.

Clients werden nacheinander behandelt, so dass keine Threading-Unterstützung benötigt wird.

Keine Leistungsvorteile.

Apartment (oder Einzel-Thread-Apartment)

COM stellt sicher, dass jeweils nur ein Client das Objekt gleichzeitig aufrufen kann. Alle Client-Aufrufe verwenden den Thread, in dem das Objekt erstellt wurde.

Objekte können sicher auf Ihre eigenen Instanzdaten zugreifen, jedoch müssen globale Daten mit kritischen Abschnitten oder einer anderen Form von Serialisierung geschützt werden.

Die lokalen Variablen des Threads sind über mehrere Aufrufe hinweg zuverlässig.

Einige Leistungsvorteile.

Frei (oder Multi-Threading-Apartment)

Objekte können Aufrufe auf einer beliebigen Anzahl von Threads gleichzeitig empfangen.

Objekte müssen alle Instanz- und globalen Daten mit Hilfe von kritischen Abschnitten oder einer anderen Form der Serialisierung schützen.

Die lokalen Variablen des Threads sind bei mehreren Aufrufen nicht zuverlässig.

Both

Dies entspricht dem freien Threading-Modell, mit der Ausnahme, dass ausgehende Aufrufe (z.B. Callbacks) mit Gewähr im selben Thread ausgeführt werden.

Maximale Leistung und Flexibilität.

Setzt nicht voraus, dass die Anwendung Thread-Unterstützung für Parameter bereitstellt, die an ausgehende Anrufe übergeben werden.

Neutral

Mehrer Clients können das Objekt gleichzeitig in verschiedenen Threads aufrufen, aber COM stellt sicher, dass die Aufrufe nicht miteinander in Konflikt geraten.

Sie müssen Thread-Konflikten vorbeugen, die globale Daten und Instanzdaten betreffen, auf die von mehreren Methoden zugegriffen wird. Dieses Modell sollte nicht bei Objekten verwendet werden, die eine Benutzeroberfläche besitzen (visuelle Steuerelemente).

Das Modell steht nur unter COM+ zur Verfügung. Es wird unter COM auf das Apartment-Modell abgebildet.

Hinweis: Lokale Variablen (ausgenommen solche in Callbacks) sind immer sicher, unabhängig davon, welches Threading-Modell verwendet wird. Dies liegt daran, dass lokale Variablen im Stack gespeichert werden und jeder Thread über einen eigenen Stack verfügt. Bei Verwendung des freien Threading-Modells sind lokale Variablen eventuell nicht in Callbacks sicher.

Über das im Experten gewählte Threading-Modell wird festgelegt, wie das Objekt in der Systemregistrierung eingetragen wird. Sie müssen sicherstellen, dass Ihre Objektimplementierung dem gewählten Threading-Modell entspricht. Allgemeine Informationen zum Erstellen von threadsicherem Quelltext finden Sie unter Multithread-Anwendungen entwickeln.

Für In-Process-Server gilt: Das Festlegen des Threading-Modells im Experten bewirkt, dass der Threading-Modell-Schlüssel im CLSID-Registrierungseintrag gesetzt wird.

Out-of-Process-Server werden als .EXE-Dateien registriert, und Delphi initialisiert COM für das höchste erforderliche Threading-Modell. Wenn beispielsweise eine .EXE-Datei ein Objekt mit freiem Threading enthält, wird dies für freies Threading initialisiert. Das bedeutet, dass es die erwartete Unterstützung für alle in der .EXE-Datei enthaltenen Objekte bereitstellen kann, die mit dem freien oder mit dem Apartment-Modell arbeiten. Verwenden Sie zur manuellen Überschreibung des Threading-Verhaltens in EXE-Dateien die Variable ComObj.CoInitFlags.

Ein Objekt schreiben, das das freie Threading-Modell unterstützt

Verwenden Sie das freie Threading-Modell und nicht das Apartment-Modell, wenn der Zugriff auf ein Objekt von mehr als einem Thread aus nötig ist. Ein häufiges Beispiel hierfür ist eine Client-Anwendung, die mit einem Objekt auf einem Remote-Computer verbunden ist. Wenn der Remote-Client eine Methode für das Objekt aufruft, empfängt der Server den Aufruf auf einem Thread aus dem Thread-Pool auf dem Server-Computer. Dieser Empfangs-Thread nimmt den Aufruf lokal für das tatsächliche Objekt vor. Da das Objekt das freie Threading-Modell unterstützt, kann der Thread einen direkten Aufruf im Objekt durchführen.

Wenn das Objekt in einem solchen Fall das Apartment-Threading-Modell unterstützt, hätte der Aufruf zu dem Thread zurückgeführt werden müssen, mit dem das Objekt erstellt worden ist, und das Ergebnis hätte an den Empfangs-Thread geliefert werden müssen, bevor es zum Client zurückgegeben worden wäre. Für diesen Ansatz ist also ein gesonderter Marshaling-Mechanismus erforderlich.

Wenn das freie Threading-Modell unterstützt werden soll, müssen Sie in Betracht ziehen, wie für die einzelnen Methoden auf die Instanzdaten zugegriffen werden kann. Wenn eine Methode in Instanzdaten schreibt, müssen Sie zum Schutz der Instanzdaten kritische Abschnitte oder eine andere Art der Serialisierung verwenden. Wahrscheinlich ist der Systemaufwand zum Serialisieren kritischer Aufrufe geringer als das Ausführen von COM-Marshaling-Code.

Beachten Sie, dass bei schreibgeschützten Daten keine Serialisierung benötigt wird.

In-Process-Server mit freiem Threading können die Leistungsfähigkeit verbessern, indem Sie als äußeres Objekt in einer Aggregation mit dem Marshaler mit freiem Threading fungieren. Der Marshaler mit freiem Threading bietet eine Abkürzung zur Standard-Thread-Verarbeitung von COM, wenn eine DLL mit freiem Threading von einem Host (Client) aufgerufen wird, der nicht mit freiem Threading arbeitet.

Für eine Aggregation mit dem freien Threading-Marshaler müssen Sie

  • CoCreateFreeThreadedMarshaler aufrufen, wobei Sie die Schnittstelle IUnknown Ihres Objekts für die Verwendung durch den sich ergebenden freien Threading-Marshaler übergeben: CoCreateFreeThreadedMarshaler(self as IUnknown, FMarshaler); CoCreateFreeThreadedMarshaler(static_cast<IUnknown *>(this), &FMarshaler);. Diese Zeile weist die Schnittstelle für den freien Threading-Marshaler einem Klassenelement, FMarshaler, zu.
  • Mit Hilfe des Typbibliothekseditors fügen Sie die Schnittstelle IMarshal dem Satz von Schnittstellen zu, die CoClass implementiert.
  • In der Methode QueryInterface Ihres Objekts delegieren Sie Aufrufe von IDD_IMarshal an den freien Threading-Marshaler (der oben als FMarshaler gespeichert wurde).

Warnung: Der freie Threading-Marshaler verletzt die normalen Regeln des COM-Marshaling, um zusätzliche Effizienz zu ermöglichen. Er sollte mit Sorgfalt eingesetzt werden. Vor allem sollte keine Aggregation mit freien Threading-Objekten in einem In-Process-Server erfolgen und keine Instantiierung durch das Objekt, das ihn (keinen anderen Thread) verwendet.

Ein Objekt schreiben, das das freie Apartment-Modell unterstützt

Beim Implementieren des Apartment-Threading-Modells (mit Einzel-Thread) müssen Sie einige Regeln beachten:

  • Der erste Thread in der Anwendung, der erstellt wird, ist der COM-Haupt-Thread. Dies ist in der Regel der Thread, mit dem WinMain aufgerufen wurde. Dies muss auch der letzte Thread sein, der die COM-Initialisierung wieder aufhebt.
  • Für jeden Thread im Apartment-Threading-Modell muss eine Nachrichtenschleife vorhanden sein, und die Nachrichtenwarteschlange muss häufig abgefragt werden.
  • Wenn ein Thread einen Zeiger zu einer COM-Schnittstelle erhält, darf der Zeiger nur in diesem Thread verwendet werden.

Das Einzel-Thread-Apartment-Modell ist ein Kompromiss zwischen der Bereitstellung der kompletten Multi-Threading-Unterstützung beim freien Threading-Modell und keiner Threading-Unterstützung. Ein Server, der nach dem Apartment-Modell arbeitet, gewährleistet, dass ein serialisierter Zugriff auf alle globalen Daten (wie z.B. den Objektzähler) möglich ist. Der Grund dafür ist, dass verschiedene Objekte unter Umständen versuchen, von verschiedenen Threads aus auf die globalen Daten zuzugreifen. Die Instanzdaten der einzelnen Objekte sind jedoch sicher, weil die Methoden jeweils über denselben Thread aufgerufen werden.

In der Regel wird für die Steuerelemente in Web-Browsern das Apartment-Threading-Modell verwendet, weil Browser-Anwendungen ihre Threads immer als Apartments initialisieren.

Ein Objekt schreiben, das das neutrale Threading-Modell unterstützt

Unter COM+ können Sie ein weiteres Threading-Modell verwenden, das zwischen freiem Threading und dem Apartment-Threading liegt: das neutrale Modell. Analog zum freien Threading-Modell ermöglicht dieses Modell mehreren Threads den gleichzeitigen Zugriff auf Ihr Objekt. Es findet kein zusätzliches Marshaling für die Übertragung auf den Thread statt, in dem das Objekt erstellt wurde. Jedoch wird gewährleistet, dass Ihr Objekt keine Aufrufe erhält, die im Konflikt miteinander stehen.

Beim Schreiben von Objekten, die das neutrale Threading-Modell verwenden, gelten weitgehend dieselben Regel wie beim Schreiben von Apartment-Threading-Objekten, mit der Ausnahme, dass Sie Instanzdaten nicht vor Thread-Konflikten schützen müssen, falls auf diese von unterschiedlichen Methoden in der Schnittstelle des Objekts aus zugegriffen werden kann. Alle Instanzdaten, auf die nur von einer einzigen Schnittstellenmethode aus zugegriffen wird, sind automatisch threadsicher.

Siehe auch