Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
Task / TaskGroup / async let
Swiftの『Task』は非同期処理の単位です。独立したタスクを作成したり、『withTaskGroup』で動的な並列処理を管理したりできます。
構文
// 新しいタスクの作成
Task {
await 非同期処理()
}
// 優先度付きタスク
Task(priority: .high) {
await 重要な処理()
}
// デタッチドタスク(現在のコンテキストから独立)
Task.detached {
await バックグラウンド処理()
}
// タスクグループ(動的な並列処理)
await withTaskGroup(of: 型.self) { group in
group.addTask { await 処理1() }
group.addTask { await 処理2() }
for await result in group {
// 各タスクの結果を処理
}
}
構文一覧
| 構文 | 概要 |
|---|---|
| Task { } | 新しい非同期タスクを作成します。現在のアクターコンテキストを継承します。 |
| Task.detached { } | 現在のコンテキストから独立したタスクを作成します。 |
| Task.cancel() | タスクをキャンセルします。 |
| Task.isCancelled | タスクがキャンセルされているか確認します。 |
| withTaskGroup(of:) | 動的な数の並列タスクを管理するタスクグループを作成します。 |
| withThrowingTaskGroup(of:) | エラーを投げるタスクグループを作成します。 |
| group.addTask { } | タスクグループにタスクを追加します。 |
サンプルコード
import Foundation
// タスクのキャンセル
let task = Task {
for i in 1...10 {
try Task.checkCancellation() // キャンセルされていれば CancellationError を throw
try await Task.sleep(nanoseconds: 100_000_000)
print("処理 \(i) 完了")
}
}
Task {
try await Task.sleep(nanoseconds: 300_000_000)
task.cancel()
print("タスクをキャンセルしました")
}
// withTaskGroup: 動的な並列処理
func fetchAllUsers(ids: [Int]) async -> [String] {
let users = [1: "Alice", 2: "Bob", 3: "Carol", 4: "Dave"]
return await withTaskGroup(of: String?.self) { group in
for id in ids {
group.addTask {
try? await Task.sleep(nanoseconds: 100_000_000)
return users[id]
}
}
var results: [String] = []
for await name in group {
if let name = name {
results.append(name)
}
}
return results
}
}
Task {
let names = await fetchAllUsers(ids: [1, 2, 3, 4, 5])
print("取得したユーザー: \(names.sorted())")
}
概要
『Task』はトップレベルや同期コードから非同期処理を開始するために使います。タスクはキャンセル可能で、長時間処理の途中で定期的に『Task.checkCancellation()』や『Task.isCancelled』を確認することが推奨されます。
『withTaskGroup』は配列の各要素を並列処理するような動的な並列処理に使います。タスク数がコンパイル時に決まらない場合に適しています。Task.detached は親のアクターコンテキストを継承しないため、UI の更新には @MainActor を明示的に指定する必要があります。
Actor についてはActor / データ競合の防止を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。