我试图在网上找到关于此的东西,但似乎没有明确的答案。我只有自己的推理,想知道什么是最好的方式。
我的应用程序运行一长串文件(大约100-200),并对其中的数据进行一些计算。每个文件都需要几分钟的时间来处理。
我最初计划根据处理器中的核心数创建任务。
因此,如果有4个核心,那么我将创建3个任务并让每个任务处理1/3的文件。
我的阅读告诉我,线程池管理所有任务,并根据各种因素为它创建线程。(简单来说?)
对我来说,为每个文件创建一个任务并允许线程池决定什么是最好的,会不会更好?
任何信息,建议都会非常受欢迎!感谢
编辑:所有文件大约为5MB,文件中数据的计算/分析非常重要。
答案 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更高的数字。考虑使用配置文件,以便根据实际性能进行更改。