You're likely overloading Swift's fixed-width thread pool used to run all concurrency work. With it generating thousands of thumbnails, there's not enough capacity left to let other work proper resume or suspend, leading to the UI issues you see. Unfortunately Swift doesn't allow you to throw the work into a separate thread pool unless do it yourself, like wrapping DispatchQueue.concurrentPerform
, which would help. If you want to stay within Swift Concurrency you can try inserting Task.yield()
at the end of every bit of work (or batch of work) to give the concurrency system a bit of time to process other work, but you'll want benchmark and see how yielding after every thumbnail or a particular number of thumbnails affects your overall performance.
This is definitely an area I'd like to see improved but I lost the pitch I was writing. It's probably a good followup to the recent default executor proposals.
Edit: found my draft pitch, [Prepitch]: Scoped, Fixed Width Concurrency Executors