Vous êtes sur le site Web historique de la documentation de 4D. Les documentations sont progressivement déplacées vers developer.4d.com

Accueil

 
4D v20.6
Objets partagés et collections partagées

Objets partagés et collections partagées  


 

Les objets partagés et les collections partagées sont des objets et des collections spécifiques dont le contenu est partagé entre les process. A la différence des variables interprocess, les objets partagés et les collections partagées ont l'avantage d'être compatibles avec les Process 4D préemptifs : il peuvent être passés en paramètres (par référence) aux commandes telles que Nouveau process ou APPELER WORKER.

Les objets partagés et les collections partagées peuvent être stockés dans des variables déclarées à l'aide des commandes standard C_OBJET et C_COLLECTION, mais doivent être instanciées à l'aide de commandes spécifiques :

Note : Des objets partagés et des collections partagées peuvent être définis comme propriétés d'objets/éléments de collections standard (non partagés).

Toute modification d'un objet ou d'une collection partagé(e) doit s'effectuer à l'intérieur d'une structure Utiliser...Fin utiliser. La lecture d'une valeur d'objet/collection ne nécessite pas de structure Utiliser...Fin utiliser.

Un catalogue unique et global, retourné par la commande Storage, est disponible à tout moment et depuis tout process de la base et de ses composants. Il peut être utilisé pour stocker tous les objets et collections partagé(e)s. 

Une fois instanciés à l'aide des commandes Creer objet partage ou Creer collection partagee, les objets partagés et les collections partagées peuvent être modifiés et lus depuis n'importe quel process.

Les modifications suivantes peuvent être effectuées sur les objets partagés et les collections partagées :

  • ajout ou suppression de propriétés d'objets, y compris d'autres objets et collections partagé(s) (ce qui crée un groupe partagé, cf. ci-dessous). 
  • ajout ou modification de valeurs (prises en charge par les objets/collections partagé(e)s).

Toute instruction de modification d'objet ou de collection partagé(e) doit être encadrée par les mots-clés Utiliser...Fin utiliser, sinon une erreur est générée.

 $s_obj:=Creer objet partage("prop1";"alpha")
 Utiliser($s_obj)
    $s_obj.prop1:="omega"
 Fin utiliser

Un objet/une collection partagé(e) ne peut être modifié(e) que par un seul process à la fois. Use/Utiliser verrouille les propriétés de l'objet/la collection pour les autres threads (process), alors que End use/Fin utiliser déverrouille l'objet/la collection partagé(e) (si le compteur de verrouillage - locking counter - et à 0, voir ci-dessous). Toute tentative de modification d'un objet/d'une collection partagé(e) sans au moins un appel à Utiliser...Fin utiliser génère une erreur.

Lorsqu'un process appelle Utiliser...Fin utiliser avec un objet/une collection partagé(e) qui est déjà "utilisé(e)" par un autre process, il est simplement mis en attente jusqu'à ce qu'il soit déverrouillé par l'appel à End use/Fin utiliser (aucune erreur n'est générée). En conséquence, les instructions situées à l'intérieur des structures Utiliser...Fin utiliser doivent toujours s'exécuter rapidement et déverrouiller les éléments dès que possible. Il est donc fortement déconseillé de modifier un objet ou une collection partagé(e) directement depuis l'interface, par exemple depuis une boîte de dialogue.

L'assignation d'objets/collections partagé(e)s à des propriétés ou éléments d'autres objets/collections partagé(e)s est autorisée et entraîne la création de groupes partagés. Un groupe partagé est automatiquement créé lorsqu'un objet ou une collection partagé(e) est assigné(e) en tant que valeur de propriété ou élément à un autre objet ou collection partagé(e). Les groupes partagés permettent d'imbriquer des objets et collections partagé(e)s mais nécessitent d'observer des règles supplémentaires :

  • L'appel de Utiliser/Use avec un objet/une collection partagé(e) appartenant à un groupe provoque le verrouillage des propriétés/éléments de tous les objets/collections partagé(e)s du groupe et incrémente son compteur de verrouillage. L'appel de End use/Fin utiliser décrémente le compteur de verrouillage du groupe et lorsque le compteur est à 0, tous les objets/collections partagé(e)s partagé(e)s sont déverrouillé(e)s.
  • Un objet ou une collection partagé(e) peut appartenir à un seul groupe partagé. Une erreur est générée si vous tentez d'assigner un objet ou une collection appartenant déjà à un groupe à un groupe différent.
  • Les objets/collections groupé(e)s ne peuvent plus être dégroupé(e)s. Une fois inclus dans un groupe partagé, un objet ou une collection partagé(e) est lié(e) définitivement au groupe pendant toute la durée de la session. Même si toutes les références de l'objet/la collection sont supprimé(e)s des objets/collections parent(e)s, ils resteront liés.

Reportez-vous à l'exemple 2 pour l'illustration des règles des groupes partagés.

Note : Les groupes partagés sont gérés via une propriété interne nommée locking identifier. Si vous avez besoin de plus d'informations sur les mécanismes utilisés, reportez-vous à la section avancée A propos du locking identifier (comment fonctionnent les groupes partagés) ci-dessous.

Lecture  

La lecture de propriétés ou d'éléments d'un objet ou d'une collection partagé(e) est possible sans appel de la structure Utiliser...Fin utiliser, même si l'objet ou la collection partagé(e) est "utilisé(e)" par un autre process.

Cependant, lorsque plusieurs valeurs sont interdépendantes et doivent être lues simultanément, il est nécessaire d'encadrer l'accès en lecture par une structure Utiliser...Fin utiliser pour des raisons de cohérence.

Par défaut, si vous appelez OB Copier/collection.copy( ) avec un objet ou une collection partagé(e) (ou contenant des objets/collections partagés), un objet ou une collection classique (non partagé(e)) est retourné(e) avec les objets contenus (le cas échéant).

Toutefois, vous pouvez utiliser le paramètre option ck shared avec ces commandes pour générer une copie partagée de l'objet ou de la collection partagé(e).

Storage  

Storage est un objet partagé unique, disponible automatiquement pour chaque application et machine. Cet objet partagé est retourné par la commande Storage. Il est destiné à référencer les objets ou collections partagé(e)s défini(e)s durant la session que vous souhaitez rendre accessibles à tous les process, préemptifs ou standard. 

A noter que, à la différence de objets partagés standard, l'objet Storage ne crée par de groupe partagé lorsque des objets/collection lui sont assigné(e)s en tant que propriétés. Cette exception permet à l'objet Storage d'être utilisé sans verrouiller les objets/collections partagé(e)s connecté(e)s.

Pour plus d'informations, reportez-vous à la description de la commande Storage.

Vous souhaitez lancer plusieurs process qui vont effectuer des tâches d'inventaire parmi différents produits et mettre à jour le même objet partagé. Le process principal instancie un objet partagé vide et ensuite lance les autres process, passant en paramètre l'objet partagé et les produits à comptabiliser :

 TABLEAU TEXTE($_items;0)
 ... //remplit le tableau avec les éléments à compter
 $nbItems:=Taille tableau($_items)
 C_OBJET($inventory)
 $inventory:=Creer objet partage
 Utiliser($inventory)
    $inventory.nbItems:=$nbItems
 Fin utiliser
 
  //Créer process
 Boucle($i;1;$nbItems)
    $ps:=Nouveau process("HowMany";0;"HowMany_"+$_items{$i};$_items{$i};$inventory)
  //l'objet partagé $inventory est passé par référence
 Fin de boucle

Dans la méthode "HowMany", l'inventaire est effectué et l'objet partagé $inventory est mis à jour dès que possible :

 C_TEXTE($1)
 C_TEXTE($what)
 C_OBJET($2)
 C_OBJET($inventory)
 $what:=$1 //pour une meilleure lisibilité
 $inventory:=$2
 
 $count:=CountMethod($what//méthode de comptage des produits
 Utiliser($inventory//Utiliser l'objet partagé
    $inventory[$what]:=$count  //stockage des résultats pour cet article
 Fin utiliser

Les exemples suivants illustrent les règles spécifiques à observer lorsque vous utilisez des groupes partagés :

 $ob1:=Creer objet partage
 $ob2:=Creer objet partage
 Utiliser($ob1)
    $ob1.a:=$ob2  //un premier groupe est créé
 Fin utiliser
 
 $ob3:=Creer objet partage
 $ob4:=Creer objet partage
 Utiliser($ob3)
    $ob3.a:=$ob4  //un 2e groupe est créé
 Fin utiliser
 
 Utiliser($ob1//Utilisation d'un objet du groupe 1
    $ob1.b:=$ob4  //ERREUR
  //$ob4 appartient déjà à un autre groupe
  //son assignation n'est pas permise
 Fin utiliser
 
 Utiliser($ob3)
    $ob3.a:=Null //on enlève la référence de $ob4 du groupe 2
 Fin utiliser
 
 Utiliser($ob1//Utilisation d'un objet du groupe 1
    $ob1.b:=$ob4  //ERREUR
  //$ob4 appartient toujours au groupe 2
  //son assignation n'est pas permise
 Fin utiliser

Note : Cette section fournit des informations concernant des mécanismes internes et pourra être utile dans des cas spécifiques uniquement.

Chaque nouvel(le) objet/collection partagé(e) est créé(e) avec un locking identifier (identifiant de verrouillage, valeur de type entier long) unique. La valeur initiale du locking identifier est toujours négative, ce qui signifie que l'objet/la collection partagé(e) est "single" (simple). Lorsqu'un objet/une collection partagé(e) "single" est défini(e) comme propriété ou élément d'un autre objet partagé ou une autre collection partagée, les deux deviennent "multiple" et un groupe partagé est créé. Ils partagent alors le même locking identifier (les propriétés/éléments héritent du locking identifier du parent) et la valeur du locking identifier devient positive.

Lorsqu'un objet partagé ou une collection partagée est retirée de son objet/collection parent(e) :

  • chacun conserve son statut "multiple"
  • ils partagent toujours le même locking identifier.

Des règles sont appliquées lorsque des objets/collections partagé(e)s sont affecté(e)s comme propriétés ou éléments à d'autres objets/collections partagés :

  • un objet/une collection "single" peut être assigné(e) à un autre objet/une autre collection "single" ou "multiple",
  • un objet/une collection "multiple" peut être assigné(e) à un autre objet/une autre collection "multiple" qui a le même locking identifier,
  • une erreur est générée si vous tentez d'assigner un objet/une collection "multiple" à un autre objet/une autre collection "single" ou "multiple" qui n'a pas le même locking identifier.

Ces règles sont illustrées dans les schémas suivants :

  1. Les objets partagés et les collections partagées (A, B, C, D) sont créés avec un "locking identifier" unique et négatif (en vert).
  2. Lorsqu'un objet single (B) est référencé dans un autre objet single (A), tous deux deviennent multiples et partagent le même locking identifier positif (en rouge). Des objets single supplémentaires peuvent être ajoutés à (A) soit directement soit à l'intérieur de (B). Tous les objets sont multiples et partagent le même locking identifier.
  3. Lorsqu'un objet multiple (B) est supprimé (déréférencé) d'un autre objet multiple (A), les deux objets restent multiples et continuent de partager le même locking identifier
  4. Les objets multiples (A, B) ne peuvent pas être utilisés comme propriétés d'un objet single (D), alors qu'un objet single (C) peut être utilisé.
  5. Les objets multiples (A, B) peuvent être utilisés comme propriétés de l'objet (D) s'ils partagent le même locking identifier. Des objets single (C) peuvent également être utilisés.

Le locking identifier des objets partagés et des collections partagées est affiché dans le débogueur en tant que propriété privée __LockerID. Vous pouvez afficher le type "Objet partagé" dans le débogueur en sélectionnant Afficher types dans le menu contextuel du débogueur :

Notez que les objets partagés et les collections partagées sont saisissables dans le débogueur tant qu'ils ne sont pas "utilisés" depuis une autre partie de l'application, auquel cas ils ne peuvent pas être modifiés. 



Voir aussi  

Creer collection partagee
Creer objet partage
OB Copier
Storage

 
PROPRIÉTÉS 

Produit : 4D
Thème : Objets (Langage)
Nom intl. : Shared objects and shared collections

 
PAGE CONTENTS 
 
HISTORIQUE 

Créé : 4D v16 R6

 
UTILISATION DE L'ARTICLE

4D - Langage ( 4D v20)
4D - Langage ( 4D v20.1)
4D - Langage ( 4D v20.2)
4D - Langage ( 4D v20.3)
4D - Langage ( 4D v20.4)
4D - Langage ( 4D v20.5)
4D - Langage ( 4D v20.6)