并行调用异步函数(Swift)

问题描述 投票:0回答:1

我们将一个整数数组(arr)传递到 cal 函数中,然后返回另一个数组,其中每个元素将传递到 multip 函数中。 乘法函数模拟需要很长时间才能得到结果。

由于我们可以对arr中的每个元素并行调用乘法函数,因此我们不必等待结果。 有没有更好的方法重写cal函数?

func multiply(_ a:Int) async throws -> Int {
    try await Task.sleep(nanoseconds: 1000_000_000)
    return a*2
}

func cal(_ arr:[Int]) async throws -> [Int] {
    try await withThrowingTaskGroup(of: (Int, Int).self) { taskGroup in
        for i in 0..<arr.count {
            taskGroup.addTask{
                let val = try await multiply(arr[i])
                return (i, val)
            }
        }
        var res = Array(repeating:0, count: arr.count)
        for try await (i,val) in taskGroup {
            res[i] = val
        } 
        return res
    }
}

var arr = [1,2,3,4]
var res = try await cal(arr)
print(res)

我在操场上尝试过我的方法。效果很好。但我对我的做法不是很熟悉。任何事情都会有帮助的。谢谢。

结果:

[2, 4, 6, 8]
swift asynchronous parallel-processing
1个回答
0
投票

虽然无法保证以真正的并行性调用异步函数,但由于线程/池以及其他内存/资源的可用性,因此在这里排除问题的主观性,您正在做什么没问题,只要您确实想等待

cal(:)
函数完成即可。

如果您不关心

cal(:)
函数被标记为
async
或者出于某种原因想要避免使用
TaskGroup
那么您可以使用两个不同的任务块来实现这一点(非常非常基本的示例):

func foo() {
    print("Running")
    Task {
        await someAsyncFunction()
        print("Awaited One")
    }
    Task {
        await someAsyncFunctionTwo()
        print("Awaited Two")
    }
    print("Finished")
}

由此,您可以期望控制台输出类似以下内容的内容(请注意,最后两行可以交换,具体取决于哪一行先完成):

Running
Finished
Awaited One
Awaited Two
© www.soinside.com 2019 - 2024. All rights reserved.