如何使用 Swift 并发限制并发(如 `maxConcurrentOperationCount`)?
How to constrain concurrency (like `maxConcurrentOperationCount`) with Swift Concurrency?
我正在尝试执行一系列网络请求,并希望在新的 Swift 并发系统中限制并发任务的数量。对于操作队列,我们将使用 maxConcurrentOperationCount
. In Combine, flatMap(maxPublishers:_:)
。新 Swift 并发系统中的等价物是什么?
例如,它不是很相关,但请考虑:
func download() async throws {
try await withThrowingTaskGroup(of: Void.self) { group in
for i in 0..<20 {
let source = sourceUrl(for: i)
let destination = destinationUrl(for: i)
group.addTask {
let (url, _) = try await self.session.download(from: source)
try? FileManager.default.removeItem(at: destination)
try FileManager.default.moveItem(at: url, to: destination)
}
}
try await group.waitForAll()
}
}
这导致所有请求 运行 同时发生:
URLSession
不尊重 httpMaximumConnectionsPerHost
这一事实很有趣,但不是这里的突出问题。更一般地说,我正在寻找如何并行地限制一系列异步任务 运行 中的并发度。
可以在达到一定计数后在循环内插入一个 group.next()
调用,例如:
func download() async throws {
try await withThrowingTaskGroup(of: Void.self) { group in
for i in 0..<20 {
let source = sourceUrl(for: i)
let destination = destinationUrl(for: i)
if i >= 6 { // max of six at a time
try await group.next()
}
group.addTask {
let (url, _) = try await self.session.download(from: source)
try? FileManager.default.removeItem(at: destination)
try FileManager.default.moveItem(at: url, to: destination)
}
}
try await group.waitForAll()
}
}
结果一次不超过六个:
我正在尝试执行一系列网络请求,并希望在新的 Swift 并发系统中限制并发任务的数量。对于操作队列,我们将使用 maxConcurrentOperationCount
. In Combine, flatMap(maxPublishers:_:)
。新 Swift 并发系统中的等价物是什么?
例如,它不是很相关,但请考虑:
func download() async throws {
try await withThrowingTaskGroup(of: Void.self) { group in
for i in 0..<20 {
let source = sourceUrl(for: i)
let destination = destinationUrl(for: i)
group.addTask {
let (url, _) = try await self.session.download(from: source)
try? FileManager.default.removeItem(at: destination)
try FileManager.default.moveItem(at: url, to: destination)
}
}
try await group.waitForAll()
}
}
这导致所有请求 运行 同时发生:
URLSession
不尊重 httpMaximumConnectionsPerHost
这一事实很有趣,但不是这里的突出问题。更一般地说,我正在寻找如何并行地限制一系列异步任务 运行 中的并发度。
可以在达到一定计数后在循环内插入一个 group.next()
调用,例如:
func download() async throws {
try await withThrowingTaskGroup(of: Void.self) { group in
for i in 0..<20 {
let source = sourceUrl(for: i)
let destination = destinationUrl(for: i)
if i >= 6 { // max of six at a time
try await group.next()
}
group.addTask {
let (url, _) = try await self.session.download(from: source)
try? FileManager.default.removeItem(at: destination)
try FileManager.default.moveItem(at: url, to: destination)
}
}
try await group.waitForAll()
}
}
结果一次不超过六个: