0Pricing
Swift Academy · 课时

使用 TaskGroup 实现并行

使用 withTaskGroup 运行并行子任务,在结果到达时逐一处理,并使用会抛出错误的变体处理失败。

使用 TaskGroup 实现并行 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 1 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 3 节课。

为什么使用 TaskGroup?

TaskGroup会并行启动许多子任务,并安全地收集结果。任务组只有在所有子任务完成后才会结束。

  • 使用group.addTask启动
  • 使用异步遍历消费结果
  • 使用可抛出错误的变体传播错误

启动并收集

使用addTask启动子任务,并通过for await在结果到达时遍历它们。

func work(_ n: Int) async -> Int {
    try? await Task.sleep(nanoseconds: UInt64(50_000_000 * n)) // simulate delay
    return n * n
}

Task {
    let result = await withTaskGroup(of: Int.self) { group in
        for i in 1...4 {
            group.addTask { await work(i) }   // spawn child
        }
        var sum = 0
        for await value in group {            // values as they finish
            sum += value
        }
        return sum
    }
    print("sum =", result) // 1^2+2^2+3^2+4^2 = 30
}

汇总结果

任务组是一个结果异步序列;您可以使用reduce或循环来构建单个返回值。

func sumSquares(_ n: Int) async -> Int {
    await withTaskGroup(of: Int.self) { group in
        (1...n).forEach { i in
            group.addTask { await work(i) }
        }
        return await group.reduce(0, +)   // reduce over async sequence
    }
}

Task {
    print(await sumSquares(5)) // 55
}

可抛出错误的任务组

使用withThrowingTaskGroup传播第一个错误;取消剩余子任务以停止无效工作。

enum CalcError: Error { case boom(Int) }

func risky(_ i: Int) async throws -> Int {
    try await Task.sleep(nanoseconds: 30_000_000)
    if i == 3 { throw CalcError.boom(i) }
    return i
}

Task {
    do {
        let total = try await withThrowingTaskGroup(of: Int.self) { group in
            for i in 1...5 { group.addTask { try await risky(i) } }
            var sum = 0
            do {
                for try await v in group { sum += v }
                return sum
            } catch {
                // Cancel remaining children on error
                group.cancelAll()
                throw error
            }
        }
        print("total:", total)
    } catch {
        print("failed:", error) // boom(3)
    }
}

取消子任务

调用group.cancelAll()请求取消。子任务应检查Task.isCancelled(或Task.checkCancellation())并快速退出。

func slow(_ i: Int) async -> Int {
    for _ in 0..<5 {
        if Task.isCancelled { return -1 } // observe cancellation cooperatively
        try? await Task.sleep(nanoseconds: 20_000_000)
    }
    return i * 10
}

Task {
    let value = await withTaskGroup(of: Int.self) { group in
        for i in 1...3 { group.addTask { await slow(i) } }
        // cancel quickly (e.g., user navigated away)
        group.cancelAll()
        // Still need to drain results; cancelled children should exit fast
        var out = 0
        for await v in group { out += v }
        return out
    }
    print("after cancel, collected:", value)
}

指南

提示:

  • 当子任务数量动态变化时,优先使用任务组。
  • 使用可抛出错误的变体以实现快速失败。
  • 即使取消后,也始终耗尽任务组(循环处理结果)。
  • 让子任务保持小型,以便及时响应取消。

结构化汇合语义

快速检查:withTaskGroup能保证什么?

回顾

回顾:使用withTaskGroup启动并行工作,在结果到达时遍历它们,并优先使用可抛出错误的变体来快速失败并取消其余工作。

常见问题解答

「使用 TaskGroup 实现并行」课时是免费的吗?

是的 — 「使用 TaskGroup 实现并行」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 3 节课。

「使用 TaskGroup 实现并行」这节课中我会学到什么?

使用 withTaskGroup 运行并行子任务,在结果到达时逐一处理,并使用会抛出错误的变体处理失败。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Swift Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 3 节。

「使用 TaskGroup 实现并行」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Swift Academy 课中编写并运行代码吗?

能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 使用 TaskGroup 实现并行
  2. 参与者与数据隔离、nonisolated
  3. Sendable 与线程安全检查
← 返回 Swift Academy