Cancellation and Timeout
Cancellation produces no error; it follows negotiation semantics: the function declares itself cancellable, and when cancelled it returns a value through an ordinary return in its body — the task completes normally.
The cancellable Function
import Async.*;
cancellable async func Work() -> int
{
await 5s;
if cancel.requested
{
return -1;
}
return 42;
}Once marked cancellable, the function body gains cancel.requested and cancel.token.
cancel and timeout
async func main() -> int
{
val cts = new CancellationTokenSource();
val t = Work() cancel cts.Token;
cts.Cancel();
print(await t);
print(await Work() timeout 100ms);
return 0;
}-1
-1timeout on a task Value
A spawn result stored in a variable can still be given a deadline; the syntax is the timeout suffix:
val t = spawn
{
await 5s;
return 99;
};
val t2 = t timeout 500ms;
print(await t2);0At the timeout deadline, the underlying task is finalized as cancelled: no parallel new task is produced — it is the decorated task itself that reaches a terminal state, and await t2 continues with the type’s default value.
Combinators
async func Quick() -> int
{
await 20ms;
return 9;
}
val both = await all([Quick(), Quick()]);
print(both);
val first = await any([Quick(), Quick()]);
print(first);[9, 9]
9all: completes only when every task completes, returning alist<T>. The first failure short-circuits into a fault; the process exits with the error and the remaining tasks stop executing;any: the first terminal state decides the result, returning aT. The other tasks are not cancelled and keep running: if the clock keeps advancing afteranyreturns, the losing tasks run to completion as usual — to stop them you must cancel them yourself;allSettled: waits for every terminal state; the returned list is ordered by input order (not completion order), with no short-circuit.
The operands take a list<task<T>> or task<T>[]. You can also write it directly: await all([A() cancel ct, B() cancel ct]); after cancellation, each returns its negotiated value.
The Token Family
The token types live in the std::Async module: CancellationTokenSource has Cancel(), CancelAfter(d), and the Token property; the CancellationToken struct has IsCancellationRequested, CanBeCanceled, and the static None().
Notes
- spawn has a cancellable form too: the body of
spawn cancel ct { }is an anonymous cancellable environment, withcancel.*available inside; cancel.*is not visible inside nested lambdas / ordinary nested function bodies, and such a body may not shadow the namecancel.
