1

I got a question for .NET 4.0 TPL programmers. I created this TPL and ThreadPool stress tester where i run X tests, each test executes Y number of tasks, when finishes, it continues to the next test.

The issue i have is that if a single test starts 100 tasks, the following test will add more tasks and so on, leaving me with huge amount of threads.

(The thread count i have is taken from Resource Monitor).

pseudo code:

while (tasksLeftToRun != 0)
{
    var nextTask = new Task(new Action(()=>
    {
        Thread.Sleep(20);
    }), cancellationToken);

    nextTask.Start();
    nextTask.ContinueWith((t) =>
    {
        //...
    },TaskScheduler.Default);
    tasksLeftToRun--;
}

About 15 seconds after the application finishes with the tests, the thread count drops to ~7.

Thanks!

Moshe Derri
  • 206
  • 2
  • 11

1 Answers1

2

The problem is that you're using Thread.Sleep instead of actual work, so the ThreadPool sees that you have blocked threads, and starts injecting new threads. This will cause the thread count to grow over time.

If you were to do real work instead of just sleeping, this would not happen, as the ThreadPool would see that the threads were actually performing work, and new threads would not speed up the overall throughput.

Now, in this case, you're continuation appears to be the bulk of the real work, in which case you're better off without the initial task at all:

while (tasksLeftToRun != 0)
{
    var nextTask = new Task.Factory.StartNew(()=>
    {
        //... Actual work
    }), cancellationToken);

    tasksLeftToRun--;
}

However, as it appears you're working on a "queue" of tasks (you have so many tasks to create), you may want to investigate whether the Parallel class is a better fit for this. If the "work" is stored in some form of collection, using Parallel.ForEach or even PLINQ may be more appropriate.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • First of all, thanks both for the fast response and the answer, its working now (decreasing threads count). I cant use StartNew because i need the task's configuration before the actual execution. About the actual lifetime of the thread - the threads im creating might take 10 seconds and up to minutes. Will it be ok to use LongRunning? – Moshe Derri Mar 14 '13 at 15:58
  • @MosheDerri What do you mean about "i need the task's configuration before the actual execution"? You can specify this in StartNew. As for long running - I wouldn't recommend it, unless you really need it. This will cause each task to use a dedicated thread, and NOT run on the ThreadPool. You'll get 1 thread / task (immediately), which will likely over saturate your processor if this is CPU based. – Reed Copsey Mar 14 '13 at 16:00