ASP.Net can limit the number of threads used even for TPL in a very neat way. Simply by creating a TaskScheduler, which is limited to one thread and starting the ASP.Net request on given TaskScheduler. I bet, they would have a pool of these limited TaskScheuler's, it would make sense...
Then what will happen inside the task processing ASP.Net request when you call TPL or PLINQ?
It is scheduling tasks using calls to Task.Start or even better and by TPL team the more preferred way, Task.Factory.StartNew.
BUT, BUT, BUTT:), these are scheduling tasks on top of TaskScheduler.Current and that is our limited TaskScheduler we are already running on! So all the scheduled tasks will be burned on the limited TaskScheduler no matter how many cores your machine has.
On the other hand, it seems that async/await operations are using new Task.Run() introduced in .Net 4.5+ and it was suggested, that it is scheduling tasks on TashScheduler.Default, what is the ThreadPool itself, so no limitation there, other than the number of cores. I do not have proof though other than this lead: Regarding usage of Task.Start() , Task.Run() and Task.Factory.StartNew() TPL
Unfortunately AsParallel() has no overload taking TaskScheduler.
So the solution would be:
- The first one already suggested by @S K, to use class Parallel and specify the degree of parallelism. The class predates PLINQ and is using the ThreadPool as it seems fit.
- The Second idea would be to schedule on ThreadPool yourself.
- Or schedule tasks on TaskScheduler.Default, targetting ThreadPool.
- Or spawn own threads(most bad idea) for ASP.Net.
- Or use async/await to run work on TaskScheduler.Default, the ThreadPool and in the async method use AsParalel(), because there TaskScheduler.Current would be same as TaskScheduler.Default, simply the ThreadPool.
NOTE OF CAUTION: Please note, that scheduling heavy stuff on ThreadPool in ASP.Net can lead to the decreasing performance of processing ASP.Net requests...