Here's what I won't get: you say max 50 connections, but only 8 threads. Each connection, by definition, "occupies" / works in a stream. I mean, you donβt use DMA or any other magic to take the load off the CPU, so each transfer requires an execution context. If you can run 50 asynchronous requests at the same time, fine, do it - you can run them from a single thread, since calling the async read function takes virtually no time. If you, for example, have 8 cores and want to make sure that the entire core is allocated for each transfer (which will probably be dumb, but this is your code, so ...), you can start 8 transfers at once.
My suggestion is to simply run 50 asynchronous requests inside the synchronization block so that they all start before you allow them to be filled (simplifies the math). Then use the count semaphore suggested by Jeremy or the synchronized queue, as suggested by mbeckish, to keep track of the remaining work. At the end of your asynchronous callback, run the following connection (if necessary). That is, start 50 connections, then, when done, use the "completed" event handler to start the next one until all work has been completed. This should not require any additional libraries or frameworks.
Coderer
source share