0Pricing
Swift Academy · Урок

TaskGroup для параллельного выполнения

Используйте withTaskGroup для запуска дочерних задач параллельно, перебирайте результаты по мере их поступления и обрабатывайте сбои с помощью варианта, поддерживающего ошибки.

«TaskGroup для параллельного выполнения» — бесплатный урок Swift Academy на CoddyKit. Это урок 1 из 3. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 3 уроков всего.

Зачем нужен TaskGroup?

TaskGroup запускает множество дочерних задач параллельно и безопасно собирает результаты. Группа завершается только после завершения всех дочерних задач.

  • Создавайте задачи с помощью group.addTask
  • Получайте результаты с помощью for await
  • Используйте вариант с выбросом ошибок для передачи ошибок дальше

Создание и сбор результатов

Создавайте дочерние задачи с помощью 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
}

Агрегирование результатов

Группа представляет собой асинхронную последовательность результатов; используйте свёртку или цикл, чтобы получить одно возвращаемое значение.

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 для параллельного выполнения» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 3 уроков всего.

Чему я научусь в уроке «TaskGroup для параллельного выполнения»?

Используйте withTaskGroup для запуска дочерних задач параллельно, перебирайте результаты по мере их поступления и обрабатывайте сбои с помощью варианта, поддерживающего ошибки. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Swift Academy?

Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 3.

Сколько времени занимает урок «TaskGroup для параллельного выполнения»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Swift Academy?

Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. TaskGroup для параллельного выполнения
  2. Акторы и изоляция данных, nonisolated
  3. Sendable и проверка потокобезопасности
← Назад к Swift Academy