I tried the semaphore route & it worked…until it didn’t. It seems like Swift Concurrency creates only one thread per system processor core and once you have every core blocked waiting for your async work, your app is deadlocked.
The cooperative thread pool has many threads as there are cores. Ideally, they kernel-mode context switching of the threads is minimal, and all the work is done by user-mode context switching of Tasks, which is much much much faster.
For that to work though, it's imperative that your async code never blocks. If you need to call legacy code that blocks, then you should spin that off in a separate thread using all the existing techniques (e.g. a dispatch queue), and using a continuation to signal the completion of its work.
Also, isn't that Task initializer creating a new task which will always use the cooperative thread pool? It's been a while and IDR when that thread pool is or isn't used, I need to re-watch that video xD
This is the feature I’m referencing, it’s only a marker to prevent you from calling it from an async context but it’s new to 5.7. You can leave it off assuming you’re already doing that checking yourself.