Normally, the TPL scheduler should be good at how many tasks run at the same time, but if you really want to control it, My blog shows how to do this with both tasks and actions, and provides an example project that you can load and run, to see how in action.
An example of when you can explicitly limit the number of tasks at the same time is when you call your own services and do not want to overload your server.
For what you are describing, it looks like you can take more advantage of using async / wait with your tasks to prevent unnecessary thread consumption. It will depend on whether you are working with a processor or working with IO in your tasks. If it is related to IO binding, then you can benefit from using async / wait.
Regardless, you asked a question about how to limit the number of tasks performed simultaneously, so here is the code that shows how to do this using both actions and tasks.
Using action
When using actions, you can use the built-in .Net Parallel.Invoke function. Here we restrict it to running no more than 3 threads in parallel.
var listOfActions = new List<Action>(); for (int i = 0; i < 10; i++) { // Note that we create the Action here, but do not start it. listOfActions.Add(() => DoSomething()); } var options = new ParallelOptions {MaxDegreeOfParallelism = 3}; Parallel.Invoke(options, listOfActions.ToArray());
With tasks
Since you are using Tasks here, there is no built-in function. However, you can use the one I provide on my blog.
And then, having created your task list and calling the function so that they start, say, no more than three simultaneous at a time, you can do this:
var listOfTasks = new List<Task>(); for (int i = 0; i < 10; i++) { var count = i; // Note that we create the Task here, but do not start it. listOfTasks.Add(new Task(() => Something())); } Tasks.StartAndWaitAllThrottled(listOfTasks, 3);