As a general rule, there is nothing that stops the TPL to use more (or less) threads than cores.
To control the situation somewhat using TPL, my first approach would be: make sure that the threadpool max threads setting is at least 30, then parallelize the task with a maximum concurrency level of 30. Within the task, you can use a semaphore before you start the CPU-bound computation to limit concurrency to the number of cores. If you are not running under IIS or SQL server, you are able and may wish to set the minimum/maximum number of threadpool threads to 30 in order to prevent the thread pool heuristics playing with the number of threads too much. (Provided, of course, that TPL and the thread pool is not used for other purposes during this time in your application.)
The optimal number of threads depends on the situation.
Consider e.g. your scenario: your tasks are not CPU bound when they retrieve data - they are network bound. As you start the tasks, it would be wise to increase parallelism so that downloads are carried out simultaneously. Your calculations may be CPU bound, however. In that case, decreasing the number of threads so that only one thread runs per core might yield better performance.
TPL is now based on the new CLR Thread Pool.
The thread pool uses heuristics to decide about the number of threads.
There is a Channel9 video about the new thread pool with some insight.
The heuristics of the old thread pool and some bits about the new can be found here (last paragraph "What the Future Holds?").
The algorithm and the numbers were subject to changes throughout the different versions of the CLR.
It might be the case in the future as well.
There are many posts about the concurrency level, one I came across is here.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…