Async is for Latency (Waiting). Parallelism is for Throughput (Doing). In .NET, we have powerful tools to scale our async operations to thousands of concurrent requests.
Run 100 HTTP requests at once. `Task.WhenAll` starts all of them simultaneously. **Warning:** If you try to run 10,000 requests to a single database using WhenAll, you will exhaust the connection pool and crash your DB. It has no built-in limit.
The "Silver Bullet" for batch processing. It allows you to specify a **MaxDegreeOfParallelism**.
var options = new ParallelOptions { MaxDegreeOfParallelism = 10 };
await Parallel.ForEachAsync(urls, options, async (url, token) => { ... });
This processes 10 items at a time, moving to the next ones as they finish. It is safe, efficient, and easier to manage than custom semaphore logic.
Q: "How do you handle 'Task Cancellation' effectively?"
Architect Answer: "We use the **CancellationToken** pattern. Every async method in the architect's codebase should accept a `CancellationToken`. This allows the user (or a timeout) to gracefully stop an expensive operation. If we don't pass the token down the chain, we end up with 'Zombie Tasks' that continue to waste CPU and RAM even after the user has disconnected."