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 — локальная установка не требуется.
Все уроки этого курса
- TaskGroup для параллельного выполнения
- Акторы и изоляция данных, nonisolated
- Sendable и проверка потокобезопасности