[threadpool] Improve heuristic to approach optimal number of threads based on workload

This PR tries to improve the heuristic to have the optimal number of threads executing Task in the ThreadPool.

It was previously based on the number of Task enqueued in the JobQueues (the general concurrent queue and the WSQ), which often led to a huge number of threads.
It now tries to maximize the Task throughput  based on an historic for the past 5 seconds (10 * 500ms periods). It works well for workload with a lot of contention, and for mixed workload (CPU heavy for 10ms and waiting for 10-90ms). The weak case of this implementation is in case of long running (largely greater than 500ms) CPU heavy workload where it is going to put as many threads as possible (as before) which is often the number of tasks in the queue; this can be mitigated by using Parallel, by setting the maximum number of threads in the ThreadPool, or by "trusting" the OS scheduler.