I want to do download say 10 files from internet, but only process max 3 at a time. It seems a Semaphore is a common solution. My internet call is an async function. I haven't found any code examples that combine these two.
Problem to solve:
- async function to download 10 files
- max 3 files processing at one time
- wait until all files processed before returning from function
Problems I'm having:
- semaphore.wait() does not work in async function
- I need wait to wait until all 10 files have processed before leaving function
Goofy solution?
- I'm calling Task.detached each loop to create new thread. Seems like a better solution should exist
Code sample:
func downloadAllFiles() async -> (String) {
// Download 10 files, but max 3 at a time
var urls = MArray<String>() ; for _ in 1 ... 10 { urls.add("https://google.com") }
let semaphore = DispatchSemaphore(value: 3)
for url in urls {
semaphore.wait() // wait if 3 already in progress ; doesn't work in async context
Task.detached(priority: .high) { // other priority options will general "lower QoS thread" warning
let web = await MWeb.call(url: url)
semaphore.signal() // allow next download to start
}
}
await Task.WhenAll(tasks) // *** C# code: need some way to wait until all tasks done before returning
return ("")
}
If I run my code in non-async world, it seems to work, but I'd like to call such a function within in async process.
Can someone help with guidance?