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

Do I need to worry about the number of tasks I create?

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

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

我原本打算根据处理器中的核心数创建任务。

所以如果有 4 个核心,那么我会创建 3 个任务,让每个任务处理 1/3 的文件。

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

对我来说,简单地为每个文件创建一个任务并让线程池决定什么是最好的会更好吗?

非常欢迎任何信息、建议!谢谢

编辑:所有文件大约 5MB,文件中数据的 calculations/analysis 占用处理器资源。

based on a variety of factors

这是一个关键点。对于满负载下的非 CPU 绑定工作,(对我而言)无法预测实际上有多少线程 运行。 .NET 线程池启发式算法非常不稳定(主观上:疯狂),不应依赖。

allow the thread pool to decide what is best

它不可能知道。它(大部分)擅长调度 CPU 绑定工作,但无法为 IO 绑定工作找到最佳并行度。

使用 PLINQ:

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

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

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

200 个文件并不是一个很长的列表,但我仍然建议不要让 ThreadPool 充满待处理的任务。

您可以为此使用 TPL 数据流的 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 更大的数字。考虑使用配置文件,以便您可以根据实际性能进行更改。