A task is an object used to represent the state of a currently-executing async function. Task objects are used to identify where an async function is suspended, and the values of local variables at that suspend point.
Tasks execute concurrently in a cooperatively multitasked environment.
A task can be durational, based on a lifespan of one or more updates before it completes.
Tasks can be sequential, overlapped, staggered, and so on, in any logical order.
The sequence and overlapping flow of tasks is specified through the use of structured or unstructured concurrency expressions.
Each task can be concurrently arranged sequentially, overlapped, staggered, and so on, in any logical order of time. Internally, a task could have a caller (or even several callers), and zero or more dependent sub-tasks that form a call graph (as opposed to a call stack).
A task is similar to a thread, but has the advantage over threads in that context switching between tasks does not involve any system calls, expensive context-state saving, or processor-blocking calls, and a processor can be 100% utilized). You don’t need synchronization such as mutexes or semaphores to guard critical sections, and there is no need for support from the operating system.
The task(t:type)
class allows direct programmatic querying and manipulation of tasks in an unstructured manner, though it is generally recommended that tasks be manipulated through structured concurrency expressions for greater clarity, power and efficiency.
Currently, the only exposed function for task
is Await()
, which waits until the current task has completed. This essentially anchors a task and adds a caller for it to return to at the call point.
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
Wait(0.5) # Wait 0.5 Seconds
# Explicit start and wait until completed
# Task1 could still be running
Target1.MoveTo(Target2)
Similar to the example above, the one below uses structured concurrency expressions:
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()")