Une tâche est un objet utilisé pour représenter l'état d'une fonction asynchrone en cours d'exécution. Les objets tâches sont utilisés pour identifier l'endroit où une fonction asynchrone est suspendue ainsi que les valeurs des variables locales à cet endroit de suspension.
Les tâches s'exécutent simultanément dans un environnement multitâche coopératif.
Une tâche peut avoir une durée, basée sur la durée de vie d'une ou de plusieurs mises à jour avant qu'elle ne se termine.
Les tâches peuvent être séquentielles, se chevaucher, être décalées, etc., dans n'importe quel ordre logique.
La séquence et le flux de chevauchement des tâches sont spécifiés à l'aide d'expressions de concurrence structurée ou d'expressions de concurrence non structurée.
Chaque tâche peut être disposée simultanément de manière séquentielle, se chevaucher, être décalée, etc., dans n'importe quel ordre temporel logique. Les tâches en interne peuvent avoir un appelant (voire plusieurs) et zéro ou plusieurs sous-tâches dépendantes qui forment un graphique des appels (par opposition à une pile d'appels).
Une tâche est similaire à un thread bien que, contrairement aux threads, le changement de contexte entre les tâches n'implique aucun appel système, aucune sauvegarde coûteuse de l'état du contexte et aucun appel de blocage du processeur (un processeur peut être utilisé à 100 %). Vous n'avez besoin d'aucune fonction de synchronisation comme les mutex ou les sémaphores pour protéger les sections critiques, ni d'aucune assistance de la part du système d'exploitation.
La classe task(t:type) permet l'interrogation et la manipulation programmatique directe des tâches d'une manière non structurée, bien qu'il soit généralement recommandé de manipuler les tâches au moyen d'expressions de concurrence structurée pour plus de clarté, de puissance et d'efficacité.
Actuellement, la seule fonction exposée pour une tâche est Await(), qui attend la fin d'une tâche en cours. Le rôle de cette fonction est d'ancrer une tâche et d'ajouter un appelant pour pouvoir revenir à ce point d'appel.
spawn{AsyncFunction3()}
# Get task to query / give commands to
# starts and continues independently
Task2 := spawn{Player.MoveTo(Target1)}
Sleep(1.5) # Wait 1.5 Seconds
MyLog.Print("1.5 Seconds into Move_to()")
Task2.Await() # wait until MoveTo() completed
Comme dans l'exemple ci-dessus, l'exemple qui suit utilise des expressions de concurrence structurée :
sync:
AsyncFunction3() # Task 1
block:
Player.MoveTo(Target1) # Task 2
Sleep(0.5) # Wait 0.5 Seconds
Target1.MoveTo(Target2)
block: # Task 3
Sleep(1.5) # Wait 1.5 Seconds
MyLog.Print("1.5 Seconds into Move_to()")