1

我有一个针对 .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。

谢谢!

4

1 回答 1

2

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

如果您要进行真正的工作而不只是休眠,则不会发生这种情况,因为 ThreadPool 会看到线程实际上正在执行工作,而新线程不会加快整体吞吐量。

现在,在这种情况下,您的延续似乎是实际工作的大部分,在这种情况下,您最好完全没有初始任务:

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

    tasksLeftToRun--;
}

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

于 2013-03-14T15:44:06.470 回答