我对.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。
谢谢!
答案 0 :(得分:2)
问题是您使用Thread.Sleep
而不是实际工作,因此ThreadPool会看到您已阻止线程,并开始注入新线程。这将导致线程数随时间增长。
如果你要做真正的工作而不是只是睡觉,这不会发生,因为ThreadPool会看到线程实际上正在执行工作,而新线程不会加快整体吞吐量。
现在,在这种情况下,你的继续似乎是实际工作的主要部分,在这种情况下你最好没有初始任务:
while (tasksLeftToRun != 0)
{
var nextTask = new Task.Factory.StartNew(()=>
{
//... Actual work
}), cancellationToken);
tasksLeftToRun--;
}
但是,由于您似乎正在处理任务的“队列”(您需要创建许多任务),因此您可能需要调查Parallel
类是否更适合此类。如果“工作”存储在某种形式的集合中,使用Parallel.ForEach
甚至PLINQ可能更合适。