.NET和任务并行库

时间:2013-01-29 21:00:43

标签: .net task-parallel-library

我有一个for循环创建了4个任务,每个任务都打印出它的循环索引 - 简单的程序来测试性能

我有一个外部循环,运行上述循环1000次(迭代) 我想检查TASK和线程的性能

(1)测试1:我认为这只会创建TASK(而非线程),但我发现它使用了TPL

tasks[i] = Task.Factory.StartNew(() => Console.WriteLine(tmp));

(2)我用TaskCreationOptions.LongRunning重写了如下

tasks[i] = Task.Factory.StartNew(() => Console.WriteLine(tmp), TaskCreationOptions.LongRunning);

(3)然后我尝试使用与上面相同的代码测试THREADs而不是任务,但现在使用“new Thread”而不是工厂

for (int i = 0; i < 4; i++)
{
    var tmp = i;
    tasks[i] = new Thread(new ThreadStart(() => Console.WriteLine(tmp)));
    tasks[i].Start();
    tasks[i].Join();
}

时间结果显示最佳性能是(2),然后是(3),然后是(1)

请能解释一下性能结果的原因,并解释上面哪一个真正只是一个任务(一个O.S.进程)和哪些正在使用线程?

我尝试使用了探查器,但只能访问Visual Studio 2010 Professional,并且看起来探查器只带有permium或终极版本。

2 个答案:

答案 0 :(得分:1)

Task.Factory.StartNew(

使用ThreadPool中的线程

LongRunning意味着,每个任务都应该创建自己的线程,因为它长时间运行而且我们不想让游泳池干燥

最后一个选项只是创建线程。

您是否检查了每个案例的内存使用情况?

答案 1 :(得分:0)

在这种情况下,使用Console.WriteLine作为测试性能的操作毫无意义。在所有情况下,每次迭代都会从池中生成或重用新线程。这是一件相对昂贵的事情。这意味着,只要您的操作是微不足道的,线程产生或重用成本的开销将总是会影响您的性能测试。

如果你的线程中有一个真正的,非平凡的操作,你的案例之间的产生成本差异将不再重要。除此之外,当使用Task时,如果创建新线程或重用池中的一个线程,使用Tasks时几乎无法控制,这总是一件好事。我的建议是,当您需要在后台处理某些内容并将头痛的东西留给框架时,请使用TPL

我希望这是可以理解的。

而且,出于实际目的,如果您有大量要计算的内容并希望使用多核cpu,您还可以查看Parallel.ForeachParallel.Foreach提供的其他内容。

编辑:{{1}},喜欢的人会自行决定是否以及何时产生新线程。使用此方法将为您提供最大的灵活性,因为运行时将决定您,具体取决于处理器数量,列表大小等,如果它有意义创建新线程或者开销会增加更多。