Understand that .NET avoids creating a new OS thread for every piece of work by using a pool of reusable worker threads.
Create a scheduler that runs many small jobs using:
ThreadPool.QueueUserWorkItemTask.Run- sequential execution
public interface IWorkScheduler
{
Task RunAsync(
IReadOnlyCollection<Action> jobs,
CancellationToken cancellationToken);
}- Create
IWorkScheduler. - Implement
SequentialWorkScheduler. - Implement
ThreadPoolWorkScheduler. - Implement
TaskWorkScheduler. - Add tests proving all jobs are executed.
- Add benchmark with 100, 1,000, and 10,000 jobs.
Create jobs that only increment an atomic counter.
Then compare:
- raw
Thread - ThreadPool
- Task
- Why is raw thread creation expensive?
- Why does ThreadPool reuse threads?
- What is the difference between queueing work and waiting for work?
- What happens when jobs block for a long time?
The ThreadPool is good for many short-lived units of work. It is not magic; blocking ThreadPool threads can still hurt the application.