我是否需要担心我创建的任务数量?

时间:2015-07-06 20:40:45

标签: vb.net multithreading task-parallel-library

我试图在网上找到关于此的东西,但似乎没有明确的答案。我只有自己的推理,想知道什么是最好的方式。

我的应用程序运行一长串文件(大约100-200),并对其中的数据进行一些计算。每个文件都需要几分钟的时间来处理。

我最初计划根据处理器中的核心数创建任务。

因此,如果有4个核心,那么我将创建3个任务并让每个任务处理1/3的文件。

我的阅读告诉我,线程池管理所有任务,并根据各种因素为它创建线程。(简单来说?)

对我来说,为每个文件创建一个任务并允许线程池决定什么是最好的,会不会更好?

任何信息,建议都会非常受欢迎!感谢

编辑:所有文件大约为5MB,文件中数据的计算/分析非常重要。

2 个答案:

答案 0 :(得分:2)

  

基于多种因素

这是关键点。对于我来说,在满负载下为非CPU绑定工作实际运行多少个线程是不可预测的。 .NET线程池启发式非常不稳定(主观上:疯狂),不应该依赖它。

  

允许线程池决定什么是最好的

它无法知道。 (主要)擅长调度受CPU限制的工作,但它无法为IO绑定工作找到最佳并行度。

使用PLINQ:

myFiles
.AsParallel().WithDOP(optimalDopHere)
.ForAll(x => Process(x));

根据经验确定最佳并行度。

如果这是纯粹受CPU限制的工作,你可以使用几乎任何并行构造,可能Parallel或仍然是PLINQ。

答案 1 :(得分:2)

200个文件不是一个很长的列表,但我仍然建议不要使用挂起的任务充斥ThreadPool。

您可以使用TPL Dataflow的ActionBlock。您可以创建块,为每个项目执行操作,并将并行性限制为您想要的任何内容。

C#中的示例:

var block = new ActionBlock<string>(async fileName =>
{
    var data = await ReadFileAsync(fileName);
    ProcessData(data);
}, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 50 });

foreach (var fileName in fileNames)
{
    block.Post(fileName);
}

block.Complete();
await block.Completion;

由于它不仅仅是一个CPU绑定操作,因此您应该使用比可用CPU更高的数字。考虑使用配置文件,以便根据实际性能进行更改。