TaskSource is an explicit async lifetime scope used to safely run async logic that belongs to something inside the game, rather than to the game session as a whole (see GameTask).
A TaskSource represents whether async logic is still allowed to continue.
It is automatically linked to the current game session and becomes invalid when the engine determines that the owning context is no longer valid (for example, when the session ends or the engine invalidates the source).
Unlike GameTask, which is global and session-scoped, TaskSource provides object-level safety by enforcing lifetime checks after every await. When a TaskSource becomes invalid, all awaiting operations throw TaskCanceledException, preventing any further async logic from running.
You do not manually expire a TaskSource from game code. Instead, you structure your async logic so it naturally stops when the source becomes invalid.
Example:
An explosive crate object that has an arming delay.
class ExplosiveCrate
{
TaskSource ts;
public void Spawn()
{
ts = new TaskSource();
_ = Arm();
}
async Task Arm()
{
await ts.DelaySeconds(3);
Explode(); // only runs if the TaskSource is still valid
}
}In this example, the async logic is explicitly scoped to the crate via TaskSource.
If the engine invalidates the source before the delay completes, the await is canceled and Explode() is never called.
The advantage of this approach is that async lifetime rules are enforced by the engine, not by manual flags or checks.
If GameTask were used here instead, the async delay would continue even if the crate no longer exists, potentially causing logic to run in an invalid state.