TPL线程计数

时间:2013-03-14 15:39:53

标签: c# .net multithreading .net-4.0 task-parallel-library

我对.NET 4.0 TPL程序员提出了一个问题。 我创建了这个TPL和ThreadPool压力测试器,我运行X测试,每个测试执行Y个任务,完成后,它继续进行下一个测试。

我遇到的问题是,如果单个测试启动100个任务,则以下测试将添加更多任务等等,这给我留下了大量的线程。

(我拥有的线程数来自资源监视器)。

伪代码:

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

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

应用程序完成测试后约15秒,线程数降至~7。

谢谢!

1 个答案:

答案 0 :(得分:2)

问题是您使用Thread.Sleep而不是实际工作,因此ThreadPool会看到您已阻止线程,并开始注入新线程。这将导致线程数随时间增长。

如果你要做真正的工作而不是只是睡觉,这不会发生,因为ThreadPool会看到线程实际上正在执行工作,而新线程不会加快整体吞吐量。

现在,在这种情况下,你的继续似乎是实际工作的主要部分,在这种情况下你最好没有初始任务:

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

    tasksLeftToRun--;
}

但是,由于您似乎正在处理任务的“队列”(您需要创建许多任务),因此您可能需要调查Parallel类是否更适合此类。如果“工作”存储在某种形式的集合中,使用Parallel.ForEach甚至PLINQ可能更合适。