Saltar al contenido principal
Versión: 20 R5 BETA

Objetos y colecciones compartidos

Shared objects and shared collections are specific objects and collections whose contents are shared between processes. In contrast to interprocess variables, shared objects and shared collections have the advantage of being compatible with preemptive 4D processes: they can be passed by reference as parameters to commands such as New process or CALL WORKER.

Shared objects and shared collections are stored in standard Object and Collection type variables, but must be instantiated using specific commands:

nota

Los objetos y colecciones compartidos pueden definirse como propiedades de objetos o colecciones estándar (no compartidos).

In order to modify a shared object/collection, the Use...End use structure must be called. Reading a shared object/collection value does not require Use...End use.

A unique, global catalog returned by the Storage command is always available throughout the application and its components, and can be used to store all shared objects and collections.

Utilización de objetos o colecciones compartidos

Once instantiated with the New shared object or New shared collection commands, shared object/collection properties and elements can be modified or read from any process of the application, under certain conditions.

Modificación

Las siguientes modificaciones pueden efectuarse en objetos y colecciones compartidos:

  • añadir o eliminar propiedades de los objetos,
  • añadir o editar valores (siempre que se soporten en objetos compartidos), incluyendo otros objetos compartidos o colecciones (lo que crea un grupo compartido, ver abajo).

All modification instructions in a shared object or collection require to be protected inside a Use...End use block, otherwise an error is generated.

 $s_obj:=New shared object("prop1";"alpha")
Use($s_obj)
$s_obj.prop1:="omega"
End Use

For conveniency, all collection functions that modify the shared object or collection insert an internal Use...End use block so you do not have to code it yourself. Por ejemplo:

$col:=Nueva colección compartida()
$col.push("alpha") //.push() desencadena internamente el uso de Use/End, por lo que no es necesario que lo hagan ustedes mismos

If you need to execute several modifications on the same collection, you can protect all modifications with a single Use...End use so that modifications are performed atomically.

$col:=Storage.mySharedCollection
Use($col)
$col[0]:="omega" //modifying an element requires to be performed inside Use/End use
$col.push("alpha") //.push() internally triggers Use/End use, but we want to do both modifications atomically
End Use

Un objeto/una colección compartido(a) sólo puede modificarse por un proceso a la vez. Use locks the shared object/collection from other threads, while End use unlocks the shared object/collection (if the locking counter is at 0, see below). . Trying to modify a shared object/collection without at least one Use...End use generates an error. When a process calls Use...End use on a shared object/collection that is already in use by another process, it is simply put on hold until the End use unlocks it (no error is generated). Consequently, instructions within Use...End use structures should execute quickly and unlock the elements as soon as possible. Por lo tanto, se recomienda enfáticamente evitar modificar un objeto o colección compartido directamente desde la interfaz, por ejemplo, a través de una caja de diálogo.

Assigning shared objects/collections to properties or elements of other shared objects/collections is allowed and creates shared groups. Un grupo compartido se crea automáticamente cuando un objeto/colección compartido se define como valor de propiedad o elemento de otro objeto/colección compartido. Los grupos compartidos permiten anidar objetos y colecciones compartidos, pero imponen reglas adicionales:

  • Calling Use on a shared object/collection belonging to a group locks properties/elements of all shared objects/collections of the group and increments its locking counter. Calling End use decrements the locking counter of the group and when the counter is at 0, all the linked shared objects/collections are unlocked.
  • Un objeto/colección compartido sólo puede pertenecer a un grupo compartido. Se devuelve un error si se intenta asignar un objeto/colección compartido ya agrupado a un grupo diferente.
  • Los objetos/colecciones compartidos agrupados no se pueden desagrupar. Una vez incluido en un grupo compartido, un objeto/colección compartido queda vinculado permanentemente a ese grupo durante toda la sesión. Incluso si todas las referencias de un objeto/colección se eliminan del objeto/colección padre, seguirán vinculadas.

Consulte el ejemplo 2 para ver una ilustración de las reglas de los grupos compartidos.

Note: Shared groups are managed through an internal property named locking identifier. Para obtener información detallada sobre este valor, consulte la Referencia del Lenguaje 4D.

Lectura

Reading properties or elements of a shared object/collection is allowed without having to call the Use...End use structure, even if the shared object/collection is in use by another process.

However, it is necessary to read a shared object/collection within Use...End use when several values are linked together and must be read at once, for consistency reasons.

Duplication

Calling OB Copy with a shared object (or with an object containing shared object(s) as properties) is possible, but will return a standard (not shared) object including its contained objects (if any).

Storage

Storage is a unique shared object, automatically available on each application and machine. This shared object is returned by the Storage command. Puede utilizar este objeto para hacer referencia a todos los objetos/colecciones compartidos definidos durante la sesión que desee que estén disponibles desde cualquier proceso preventivo o estándar.

Note that, unlike standard shared objects, the storage object does not create a shared group when shared objects/collections are added as its properties. This exception allows the Storage object to be used without locking all connected shared objects or collections.

For more information, refer to the Storage command description.

Use...End use

The formal syntax of the Use...End use structure is:

 Use(Shared_object_or_Shared_collection)
instrucción(es)
End use

The Use...End use structure defines a sequence of statements that will execute tasks on the Shared_object_or_Shared_collection parameter under the protection of an internal semaphore. Shared_object_or_Shared_collection can be any valid shared object or shared collection.

Shared objects and shared collections are designed to allow communication between processes, in particular, preemptive 4D processes. Se pueden pasar por referencia como parámetros de un proceso a otro. Surrounding modifications on shared objects or shared collections by the Use...End use keywords is mandatory to prevent concurrent access between processes.

  • Once the Use line is successfully executed, all Shared_object_or_Shared_collection properties/elements are locked for all other process in write access until the corresponding End use line is executed.
  • The statement(s) sequence can execute any modification on the Shared_object_or_Shared_collection properties/elements without risk of concurrent access.
  • If another shared object or collection is added as a property of the Shared_object_or_Shared_collection parameter, they become connected within the same shared group.
  • If another process tries to access one of the Shared_object_or_Shared_collection properties or connected properties while a Use...End use sequence is being executed, it is automatically put on hold and waits until the current sequence is terminated.
  • The End use line unlocks the Shared_object_or_Shared_collection properties and all objects of the same group.
  • Several Use...End use structures can be nested in the 4D code. In the case of a group, each Use increments the locking counter of the group and each End use decrements it; all properties/elements will be released only when the last End use call sets the locking counter to 0.
nota

The following functions automatically trigger an internal Use/End use, making an explicit call to the structure unnecessary when the function is executed:

Ejemplo 1

Se desea lanzar varios procesos que realicen una tarea de inventario en diferentes productos y que actualicen el mismo objeto compartido. El proceso principal instancia un objeto compartido vacío y luego, lanza los otros procesos, pasando el objeto compartido y los productos a contar como parámetros:

 ARRAY TEXT($_items;0)
... //llenar el array con los elementos a contar
$nbItems:=Size of array($_items)
var $inventory : Object
$inventory:=New shared object
Use($inventory)
$inventory.nbItems:=$nbItems
End use

//Crear procesos
For($i;1;$nbItems)
$ps:=New process("HowMany";0;"HowMany_"+$_items{$i};$_items{$i};$inventory)
//$inventory object sent by reference
End for

En el método "HowMany", el inventario se realiza y el objeto compartido $inventory se actualiza lo antes posible:

    //HowMany
#DECLARE ($what : Text ; $inventory : Object)

$count:=CountMethod($what) //method to count products
Use($inventory) //use shared object
$inventory[$what]:=$count //save the results for this item
End use

Ejemplo 2

Los siguientes ejemplos ilustran las reglas específicas para el manejo de los grupos compartidos:

 $ob1:=New shared object
$ob2:=New shared object
Use($ob1)
$ob1.a:=$ob2 //group 1 is created
End use

$ob3:=New shared object
$ob4:=New shared object
Use($ob3)
$ob3.a:=$ob4 //group 2 is created
End use

Use($ob1) //use an object from group 1
$ob1.b:=$ob4 //ERROR
//$ob4 already belongs to another group
//assignment is not allowed
End use

Use($ob3)
$ob3.a:=Null //remove any reference to $ob4 from group 2
End use

Use($ob1) //use an object from group 1
$ob1.b:=$ob4 //ERROR
//$ob4 still belongs to group 2
//assignment is not allowed
End use