Shared objects und shared collections sind spezifische Objekte und Collections, deren Inhalt zwischen Prozessen geteilt wird. Im Gegensatz zu Interprozessvariablen haben "shared objects" und "shared collections" den Vorteil, dass sie mit Preemptive 4D Prozesse kompatibel sind: Sie können per Referenz als Parameter an Befehle wie New process oder CALL WORKER übergeben werden.
"Shared objects/collections" lassen sich in Variablen speichern, die mit Standardbefehlen C_OBJECT und C_COLLECTION deklariert wurden, müssen aber über spezifische Befehle eine Instanz erhalten:
Ein "shared object" erstellen Sie mit der Funktion New shared object oder OB Copy mit der Option ck shared.
Hinweis: "Shared objects/collections" lassen sich als Eigenschaften von standardmäßigen Objekten oder Collections verwenden.
Zum Ändern von "shared object/collection" muss die Struktur Use...End use aufgerufen werden. Wird ein Wert von "shared object/collection" nur gelesen, ist Use...End use nicht erforderlich.
Ein einmaliger, globaler Katalog, der von der Funktion Storage zurückgegeben wird, ist immer in der gesamten Anwendung und ihren Komponenten verfügbar. Darin lassen sich alle "shared objects/collections" speichern.
Ist mit den Funktionen New shared object oder New shared collection eine Instanz von shared object/collection erstellt, lassen sich ihre jeweiligen Eigenschaften und Elemente in jedem Prozess ändern oder lesen.
Sie können shared objects/collections folgendermaßen bearbeiten:
Objekteigenschaften ändern oder entfernen
In shared objects unterstützte Werte hinzufügen oder bearbeiten, inkl. andere shared objects/collections (was eine shared group erstellt, siehe unten).
Beachten Sie, dass alle Anweisungen zum Ändern in shared object oder collection in die Struktur Use...End use eingebettet sein müssen, sonst wird ein Fehler erzeugt.
$s_obj:=New shared object("prop1";"alpha") Use($s_obj) $s_obj.prop1:="omega" End Use
Shared object/collection lässt sich zur selben Zeit immer nur von einem Prozess verändern. Use sperrt shared object/collection für andere Threads, während End useshared object/collection entsperrt (wenn der Sperrschlüssel bei 0 ist - siehe unten). Versuchen Sie, ein shared object/collection ohne mindest ein Use...End use zu ändern, wird ein Fehler generiert. Ruft ein Prozess Use...End use in shared object/collection auf, das bereits von einem anderen Prozess benutzt wird, wird er bis zum Entsperren durch End use in Wartestellung gesetzt (es wird kein Fehler generiert). Deshalb sollten Anweisungen innerhalb der Struktur Use...End use rasch ablaufen und die Elemente so bald wie möglich entsperren und Sie sollten ein shared object/collection nicht direkt auf der Oberfläche ändern, also z.B. über ein Dialogfenster.
Shared objects/collections lassen sich auch Eigenschaften oder Elementen von anderen shared objects/collections zuweisen. Das erstellt shared groups. Eine shared group wird automatisch erstellt, wenn ein shared object/collection als Eigenschaftswert oder Element eines anderen shared object/collection gesetzt wird. Shared groups erlauben das Einbinden von shared objects/collections. Dafür gelten jedoch zusätzliche Regeln:
Der Aufruf von Use in shared object/collection innerhalb einer Gruppe sperrt die Eigenschaften/Elemente aller shared objects/collections, die zur gleichen Gruppe gehören.
Eine shared object/collection kann nur zu einer shared group gehören. Versuchen Sie, eine zu einer Gruppe gehörende shared object/collection in eine andere Gruppe zu setzen, wird ein Fehler generiert.
Die Gruppierung von shared objects/collections lässt sich nicht wieder auflösen. Gehören sie zu einer shared group, bleibt diese Zuordnung während der gesamten Sitzung erhalten. Selbst wenn alle Referenzen eines Objekts bzw. einer Collection aus dem übergeordneten Objekt bzw. der Collection entfernt werden, bleibt diese Gruppierung erhalten.
In Beispiel 2 sehen Sie die Anwendung der Regeln für shared groups.
Eigenschaften oder Elemente von shared object/collection lassen sich ohne die Struktur Use...End use lesen, selbst wenn shared object/collection von einem anderen Prozess benutzt wird.
Sind dagegen mehrere Werte logisch miteinander verbunden, sollte shared object/collection aus Konsistenzgründen in der Struktur Use...End use gelesen werden.
Standardmäßig wird bei Aufruf von OB Copy/collection.copy( ) mit shared object/collection (oder darin enthaltenen shared objects/collections) ein reguläres Objekt bzw. Collection (not shared) mit den enthaltenen Objekten (falls vorhanden) zurückgegeben.
Setzen Sie dagegen im Parameter optionck shared ein, wird eine Kopie des ursprünglichen shared object/collection erstellt.
Storage ist ein einmaliges shared object, das automatisch in jeder Anwendung und auf jedem Rechner verfügbar ist. Es wird von der Funktion Storage zurückgegeben. Sie können es verwenden, um auf alle während der Sitzung definierten shared objects/collections zu verweisen, die über jeden preemptive oder standardmäßige Prozesse verfügbar sein sollen.
Beachten Sie, dass das Storage Objekt, im Gegensatz zu den standardmäßigen shared objects, keine shared group erstellt, wenn shared objects/collections als Eigenschaft hinzugefügt werden. Auf diese Weise lässt sich das Storage Objekt ohne Sperren aller verbundenen shared objects/collections verwenden.
Weitere Informationen dazu finden Sie unter der Funktion Storage.
Mehrere Prozesse starten, die eine Inventur von verschiedenen Produkten durchführen und das gleiche shared object aktualisieren. Der Hauptprozess erstellt eine Instanz von einem leeren shared object, startet dann die anderen Prozesse und übergibt das shared object und die zu zählenden Produkte als Parameter:
ARRAY TEXT($_items;0)
... //das Array mit den zu zählenden Einträgen füllen $nbItems:=Size of array($_items) C_OBJECT($inventory) $inventory:=New shared object Use($inventory) $inventory.nbItems:=$nbItems End use
//Prozesse erstellen For($i;1;$nbItems) $ps:=New process("HowMany";0;"HowMany_"+$_items{$i};$_items{$i};$inventory) //per Referenz gesendetes Objekt $inventory End for
In der Methode "HowMany" ist "inventory" ausgeführt und das shared object $inventory wird sobald wie möglich aktualisiert:
$count:=CountMethod($what) //Methode zum Zählen der Produkte Use($inventory) //shared object verwenden $inventory[$what]:=$count //Ergebnis für diesen Eintrag sichern End use
Use($ob1) //Ein Objekt aus Gruppe 1 verwenden $ob1.b:=$ob4 //ERROR //$ob4 gehört bereits zu einer anderen Gruppe //Die Zuweisung ist nicht erlaubt End use
Use($ob3) $ob3.a:=Null//Jede Referenz auf $ob4 aus Gruppe 2 entfernen End use
Use($ob1) //Ein Objekt aus Gruppe 1 verwenden $ob1.b:=$ob4 //ERROR //$ob4 gehört immer noch zu Gruppe 2 //Die Zuweisung ist nicht erlaubt End use
Hinweis:Dieser Abschnitt gibt weitere Informationen über interne Mechanismen und ist nur in ganz bestimmten Fällen nützlich.
Jedes neue shared object/collection wird mit einem einmaligen Sperrschlüssel vom Typ lange Ganzzahl erstellt. Der Anfangswert ist immer negativ, d.h. das ist "single". Wird shared object/collection mit "single" Status als Eigenschaft oder Element eines anderen shared object/collection gesetzt, werden beide "multiple" und es wird eine shared group erstellt. Sie teilen dann den gleichen Sperrschlüssel: Hinzugefügte Eigenschaften/Elemente erben den Sperrschlüssel des übergeordneten Objekts bzw. der Collection.
Wird ein shared object/collection aus dem übergeordneten Objekt bzw. der Collection entfernt:
gelten sie weiterhin als "multiple"
behalten sie den gleichen Sperrschlüssel bei
Für shared objects/collections, die als Eigenschaften oder Elemente anderer shared objects/collections gesetzt werden, gelten bestimmte Regeln:
Ein "single" Objekt/Collection lässt sich an ein anderes "single" oder "multiple" Objekt/Collection anfügen,
Ein "multiple" Objekt/Collection lässt sich an ein anderes "multiple" Objekt/Collection mit dem gleichen Sperrschlüssel anfügen,
Versuchen Sie, ein "multiple" Objekt/Collection an ein anderes "single" oder "multiple" Objekt/Collection mit einem anderen Sperrschlüssel anzufügen, tritt ein Fehler auf.
Die folgenden Abbildungen zeigen die verschiedenen Szenarien:
Shared objects und shared collections (A, B, C, D) werden mit einem internen einmaligen Sperrschlüssel (1, 2, 3, 4) erstellt.
Wird innerhalb eines single Objekts (B) auf ein single Objekt (A) verwiesen, werden beide multiple und teilen den gleichen Sperrschlüssel. Weitere single Objekte lassen sich entweder bei (A) oder innerhalb von (B) hinzufügen. Alle Objekte werden als multiple gewertet und teilen den gleichen Sperrschlüssel.
Wird ein multiple Objekt (B) von einem anderen multiple Objekt (A) entfernt (dereferenced), bleiben beide multiple und behalten den gleichen Sperrschlüssel.
Multiple Objekte (A, B) sind nicht als Eigenschaft eines single Objekts (D) verwendbar, single Objekte (C) lassen sich dagegen verwenden.
Multiple Objekte (A, B) sind als Eigenschaften des Objekts (D) verwendbar, wenn sie den gleichen Sperrschlüssel teilen. Single Objekte (C) lassen sich auch verwenden.
Der Sperrschlüssel von shared objects und shared collections erscheint im Debugger als private Eigenschaft __LockerID. Um den Typ "Shared Object" im Debugger anzuzeigen, wählen Sie im Kontextmenü den Eintrag Show Types:
Beachten Sie, dass shared objects und shared collections im Debugger eingebbar sind, solange sie nicht anderswo verwendet werden. In diesem Fall lassen sie sich nicht verändern.