Skip to content

Cancel .task work when the view disappears - #46

Merged
colemancda merged 4 commits into
masterfrom
feature/task-cancel
Jul 23, 2026
Merged

Cancel .task work when the view disappears#46
colemancda merged 4 commits into
masterfrom
feature/task-cancel

Conversation

@colemancda

Copy link
Copy Markdown
Member

.task now cooperatively cancels its async closure when the view leaves the tree, matching SwiftUI. Previously it launched a Task on appear that ran forever.

Mechanism

  • The .task modifier registers two callbacks — start and cancel — and the launched Task is stored in a registry keyed by the view's stable identity path, not by the callback id.
  • The interpreter fires start on appear (DisposableEffect enter) and cancel on onDispose.

Why key by identity path

Callback ids are generation-scoped and evicted after one cycle, but a view can re-evaluate many times between appear and disappear — so a captured cancel id would be long gone by dispose. Keying the running Task by identity path (stable across every re-evaluation) makes cancel find the right task regardless. The interpreter also hands onDispose the freshest cancel id via a remembered holder, so the callback itself stays resolvable.

The user's closure observes cancellation the normal way (Task.sleep/Task.isCancelled throw/return on cancel).

Verification

  • swift test — new start/cancel test (launches then cancels via the two ids, asserts the registry clears), 67 total passing
  • Emulator (Interaction screen, new ".task (cancels on disappear)" example, ticks a counter every 0.5s while visible):
    • Show → counter climbs
    • Hide → counter frozen at 32 across a controlled 3.5s window (zero new ticks — the background loop really stopped)
    • Show again → counter resumes (36 → 45), so start-after-cancel works too

@colemancda
colemancda merged commit eb0e2a0 into master Jul 23, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant