Una tarea es un objeto que se usa 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 el punto de suspensión.
Las tareas se ejecutan concurrentemente en un entorno multitareas cooperativo.
Una tarea puede ser duradera, en función de la vida útil de una o más actualizaciones antes de completarse.
Las tareas pueden ser secuenciales, superpuestas, escalonadas, etc. en cualquier orden lógico.
La secuencia y el flujo de superposición de tareas se especifica mediante el uso de expresiones de concurrencia no estructurada o estructurada.
Cada tarea puede organizarse concurrentemente de manera secuencial, superpuesta, escalonada, etc. en cualquier orden de tiempo lógico. Internamente, una tarea podrá tener una persona que llama (o incluso varias personas que llaman) y cero o más subtareas dependientes que forman un gráfico 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 involucra ninguna llamada de sistema, ahorro de estado de contexto o llamadas que bloquean procesadores y se puede utilizar el 100 % del procesador. No se necesita sincronización, como mutexes o semáforos para proteger las secciones críticas ni hay necesidad de compatibilidad con el sistema operativo.
La clase task(t:type) permite consulta programática directa y manipulación de tareas de manera desestructurada aunque, generalmente, se sugiere que las tareas se manipulen mediante expresiones de concurrencia estructurada para una mayor claridad, potencia y eficiencia.
Actualmente, la única función expuesta para tarea es Await(), que espera a que se complete la tarea actual. Esencialmente, esto ancla una tarea y añade una persona que llama para que regrese al punto de la 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
El siguiente ejemplo, similar al anterior, usa expresiones de concurrencia 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()")