Как ограничить параллелизм (например, `maxConcurrentOperationCount`) с помощью Swift Concurrency?

Я пытаюсь выполнить серию сетевых запросов и хотел бы ограничить количество одновременных задач в новой системе Swift Concurrency. С очередями операций мы бы использовалиmaxConcurrentOperationCount. В комбинате,flatMap(maxPublishers:_:). Что эквивалентно новой системе Swift Concurrency?

Например, это не очень актуально, но учтите:

      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интересно, но это не основная проблема здесь. Я ищу, в более общем смысле, как ограничить степень параллелизма в серии асинхронных задач, выполняющихся параллельно.

1 ответ

Можно вставить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()
    }
}

В результате получается не более шести одновременно:

Другие вопросы по тегам