Each of my tasks may have different return values, so I wrote this method, but it looks a bit strange.
func withThrowingTask2<T1, T2>(t1: @escaping () async throws -> T1, t2: @escaping () async throws -> T2) async throws -> (T1, T2) {
try await withThrowingTaskGroup(of: [Int: Any?].self) { group in
group.addTask { try await [0: t1()] }
group.addTask { try await [1: t2()] }
let result = try await group.reduce([Int: Any?]()) { partialResult, result in
partialResult.merging(result, uniquingKeysWith: { $1 })
}
return (result[0] as! T1, result[1] as! T2)
}
}