Zadanie (task) jest obiektem używanym do reprezentowania stanu aktualnie wykonywanej funkcji asynchronicznej. Za pomocą obiektów zadań można zidentyfikować miejsce zawieszenia funkcji asynchronicznej oraz wartości lokalnych zmiennych w tym punkcie zawieszenia.
Zadania wykonywane są współbieżnie w środowisku wielozadaniowym opartym na współpracy.
Zadanie może być czasowe, w oparciu o czas życia jednej lub więcej aktualizacji przed jego zakończeniem.
Zadania mogą być sekwencyjne, nakładać się na siebie, być rozłożone w czasie itd. w dowolnej logicznej kolejności.
Sekwencja i nakładanie się przepływu zadań jest określane za pomocą ustrukturyzowanych lub nieustrukturyzowanych wyrażeń współbieżności.
Każde zadanie może być współbieżnie ułożone sekwencyjnie, nałożone na siebie, rozłożone w czasie itd. w dowolnej logicznej kolejności. Wewnętrznie zadanie może mieć wywoływacza (lub nawet kilka wywoływaczy) i zero lub więcej zależnych podzadań, które tworzą graf wywołań (w przeciwieństwie do stosu wywołań).
Zadanie jest podobne do wątku, ale ma tę przewagę nad wątkami, że przełączanie kontekstu między zadaniami nie wymaga żadnych wywołań systemowych, obciążającego zapisywania stanu kontekstu ani wywołań blokujących procesor, a procesor może być wykorzystywany w 100%). Nie potrzebujesz synchronizacji takich jak mutexy lub semafory do ochrony krytycznych sekcji i nie ma potrzeby wsparcia ze strony systemu operacyjnego.
Klasa task(t:type) pozwala na bezpośrednie programowe odpytywanie i manipulowanie zadaniami w nieustrukturyzowany sposób, choć ogólnie zaleca się manipulowanie zadaniami za pomocą strukturalnych wyrażeń współbieżności dla większej przejrzystości, mocy i wydajności.
Obecnie jedyną uwidocznioną funkcją dla zadania jest Await(), która czeka na zakończenie bieżącego zadania. Zasadniczo zakotwicza to zadanie i dodaje wywoływacza, do którego może ono powrócić w punkcie wywołania.
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
Podobnie jak w powyższym przykładzie, poniższy wykorzystuje strukturalne wyrażenia współbieżności:
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()")