Skip to content

Instantly share code, notes, and snippets.

@eastlondoner
Created January 3, 2025 14:03
Show Gist options
  • Save eastlondoner/51f5da85def57c595c239cc680f47fcd to your computer and use it in GitHub Desktop.
Save eastlondoner/51f5da85def57c595c239cc680f47fcd to your computer and use it in GitHub Desktop.
Swift Concurrency Notes

In Swift’s concurrency model, you can handle multiple concurrent streams of work using async let or the TaskGroup API. Both approaches allow you to perform concurrent tasks and wait for their results.

Option 1: Using async let

async let is a concise way to launch multiple tasks concurrently and wait for their results.

func fetchData() async throws -> (String, Int, Bool) { async let stringResult = doSomethingAsync() async let intResult = somethingElseAsync() async let boolResult = thirdThingAsync()

// Wait for all tasks to complete
return try await (stringResult, intResult, boolResult)

}

Here: • Each async let runs concurrently. • try await gathers their results. If any task throws, the error is propagated.

Option 2: Using TaskGroup

TaskGroup offers more flexibility, especially if the number of tasks is dynamic or the results need to be processed as they complete.

func fetchData() async throws -> [Any] { try await withThrowingTaskGroup(of: Any.self) { group in group.addTask { try await doSomethingAsync() } group.addTask { try await somethingElseAsync() } group.addTask { try await thirdThingAsync() }

    var results: [Any] = []
    for try await result in group {
        results.append(result)
    }
    return results
}

}

Here: • withThrowingTaskGroup manages the tasks in the group. • Results are processed as each task completes. • If a task throws, the error is propagated, and other tasks may be canceled.

Option 3: Fire-and-Forget Tasks

If you don’t need the results immediately (or at all), you can use detached tasks or Task.

Task { async let _ = doSomethingAsync() async let _ = somethingElseAsync() async let _ = thirdThingAsync() // No need to await, tasks will run concurrently }

Key Points: 1. Error Handling: • async let and TaskGroup propagate errors if any task fails. • Fire-and-forget tasks don’t handle errors unless explicitly managed. 2. Concurrency Control: • Tasks launched with async let or TaskGroup run in parallel but respect structured concurrency. 3. TaskGroup for Dynamic Work: • Use TaskGroup if the number of tasks isn’t fixed or results need to be processed dynamically.

Choose the method based on the complexity and requirements of your use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment