Generic Function

withThrowingTaskGroup(of:returning:body:)

Starts a new scope that can contain a dynamic number of throwing child tasks.

Declaration 宣言

func withThrowingTaskGroup<ChildTaskResult, GroupResult>(of childTaskResultType: ChildTaskResult.Type, returning returnType: GroupResult.Type = GroupResult.self, body: (inout ThrowingTaskGroup<ChildTaskResult, Error>) async throws -> GroupResult) async rethrows -> GroupResult where ChildTaskResult : Sendable

Discussion 解説

A group waits for all of its child tasks to complete, throw an error, or be canceled before it returns. After this function returns, the task group is always empty.

To collect the results of the group’s child tasks, you can use a for-await-in loop:


var sum = 0
for await result in group {
    sum += result
}

If you need more control or only a few results, you can call next() directly:


guard let first = await group.next() else {
    group.cancelAll()
    return 0
}
let second = await group.next() ?? 0
group.cancelAll()
return first + second

Task Group Cancellation タスクグループ取り消し

You can cancel a task group and all of its child tasks by calling the cancellAll() method on the task group, or by canceling the task in which the group is running.

If you call async(priority:operation:) to create a new task in a canceled group, that task is immediately canceled after creation. あなたがasync(priority:operation:)を呼び出すことで新しいタスクをある取り消されたグループの中に作成するならば、そのタスクは作成の後に直ぐに取り消されます。 Alternatively, you can call asyncUnlessCancelled(priority:operation:), which doesn’t create the task if the group has already been canceled Choosing between these two functions lets you control how to react to cancellation within a group: some child tasks need to run regardless of cancellation, but other tasks are better not even being created when you know they can’t produce useful results.

Throwing an error in one of the tasks of a task group doesn’t immediately cancel the other tasks in that group. あるエラーをタスクグループのタスクそれらの1つにおいてスローすることは、直ぐにそのグループの中の他のタスクを取り消しません。 However, if you call next() in the task group and propagate its error, all other tasks are canceled. For example, in the code below, nothing is canceled and the group doesn’t throw an error: 例えば、下のコードにおいて、何も取り消されません、そしてグループはエラーをスローしません:


withThrowingTaskGroup { group in
    group.addTask { throw SomeError() }
}

In contrast, this example throws SomeError and cancels all of the tasks in the group: 対照的に、この例はSomeErrorをスローします、そしてそのグループの中の全てのタスクを取り消します:


withThrowingTaskGroup { group in
    group.addTask { throw SomeError() }
    try group.next()
}

An individual task throws its error in the corresponding call to Group.next(), which gives you a chance to handle the individual error or to let the group rethrow the error.