Una tarea es un objeto que se utiliza para representar el estado de una función asíncrona actualmente en ejecución. Los objetos de tarea se utilizan para identificar dónde se suspende una función asíncrona, y los valores de las variables locales en ese punto de suspensión.
Las tareas se ejecutan simultáneamente en un entorno multitarea cooperativo.
Una tarea puede ser duracional, basada en una duración de una o más actualizaciones antes de completarse.
Las tareas pueden ser secuenciales, solaparse, escalonarse, etc., en cualquier orden lógico.
La secuencia y el flujo de solapamiento de las tareas se especifican utilizando expresiones de simultaneidad estructurada o no estructurada.
Cada tarea puede estar dispuesta simultáneamente de forma secuencial, solapada, escalonada, etc., en cualquier orden lógico de tiempo. Las tareas internas pueden tener un llamador (o incluso varios) y cero o más subtareas dependientes que forman un grafo de llamadas (a diferencia de una pila de llamadas).
Una tarea es similar a un subproceso, pero tiene la ventaja de que el cambio de contexto entre tareas no implica ninguna llamada al sistema, ninguna necesidad de guardar el estado del contexto, ni llamadas de bloqueo del procesador, y un procesador puede utilizarse al 100 %). No necesitas sincronización como mutex o semáforos para proteger las secciones críticas, y no es necesario el apoyo del sistema operativo.
La clase task(t:type) permite la consulta y manipulación programática directa de las tareas de forma no estructurada, aunque generalmente se recomienda que las tareas se manipulen a través de expresiones de simultaneidad estructuradas para una mayor claridad, potencia y eficiencia.
Actualmente la única función expuesta para task es Await() que espera hasta que la tarea actual haya terminado. Esto esencialmente ancla una tarea y añade un llamador para que regrese a este punto de llamada.
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
Este ejemplo es similar al anterior y utiliza expresiones de simultaneidad estructurada:
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()")