Back to Swift Reference
⚡ ConcurrencyAdvancedSwift 5.5+

Task, Cancellation & TaskGroup

Start concurrent work, cancel it cooperatively, and fan out a dynamic number of child tasks.

Task { } starts new async work from synchronous code. Keep a reference if you need to cancel it later.

withThrowingTaskGroup runs a dynamic number of child tasks in parallel; if the parent is cancelled, all children are too (structured concurrency).

tasks-and-task-groups.swift
1func downloadThumbnails(urls: [URL]) async throws -> [Data] {
2    try await withThrowingTaskGroup(of: Data.self) { group in
3        for url in urls {
4            group.addTask {
5                try Task.checkCancellation()
6                let (data, _) = try await URLSession.shared.data(from: url)
7                return data
8            }
9        }
10        var results: [Data] = []
11        for try await data in group { results.append(data) }
12        return results
13    }
14}
15
16// Cancelling unstructured work
17let task = Task { try await downloadThumbnails(urls: []) }
18task.cancel()

Common pitfalls

  • Cancellation is cooperative — long loops must check Task.isCancelled or call Task.checkCancellation().
  • Avoid Task.detached unless you explicitly need to drop the current actor and priority.

Still unclear? Ask BeeAI about Task, Cancellation & TaskGroup.

Get a tailored explanation, or paste your own code for a Swift 6 review. Free members get daily questions — Pro is unlimited.

Ask BeeAI

Become a Founding Pro member: unlimited BeeAI, upcoming Swift paths and every new reference entry first.

See Pro Plans