You want to limit yourself to something in most cases. You always have some kind of condition when you work simultaneously with several operations. If they are connected to the CPU, then the tasks are stored in the queue ThreadPoolwaiting for the thread, and if it is asynchronized, then you have a state machine sitting on the heap.
Even asynchronous operations usually use some limited resource, be it throughput, ports, a remote database server processor, etc.
( , ). , SlimSemahpore , TPL:
var block = new ActionBlock<string>(
url => downloadAsync(url),
new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 10 });
urlList.ForEach(url => block.Post(url));
block.Complete();
await block.Completion;