【发布时间】:2015-12-05 14:16:17
【问题描述】:
我有一个场景,我必须基于处理器内核并行处理多个文件(例如 30 个)。我必须根据处理器内核的数量将这些文件分配给单独的任务。我不知道如何对要处理的每个任务进行开始和结束限制。例如,每个任务都知道它必须处理多少个文件。
private void ProcessFiles(object e)
{
try
{
var diectoryPath = _Configurations.Descendants().SingleOrDefault(Pr => Pr.Name == "DirectoryPath").Value;
var FilePaths = Directory.EnumerateFiles(diectoryPath);
int numCores = System.Environment.ProcessorCount;
int NoOfTasks = FilePaths.Count() > numCores ? (FilePaths.Count()/ numCores) : FilePaths.Count();
for (int i = 0; i < NoOfTasks; i++)
{
Task.Factory.StartNew(
() =>
{
int startIndex = 0, endIndex = 0;
for (int Count = startIndex; Count < endIndex; Count++)
{
this.ProcessFile(FilePaths);
}
});
}
}
catch (Exception ex)
{
throw;
}
}
【问题讨论】:
-
任务并行库将在后台处理多核架构。创建任务时,我们不需要关心可用的系统内核
-
我绝对不是任务并行库方面的专家,但 TPL 不应该自己处理 CPU 内核的数量,并确定“拆分”工作负载的最佳方式吗?
-
这里的问题可能是,如果目录中有100个文件,那么创建100个任务并不是一个好主意。所以你可以使用 Parallel.For 循环。它将在内部进行分区,并依靠自己的分区器建立并行处理。
-
请注意,任务和并发算法的知识还需要并发集合和线程/并发安全数据交换算法的知识。在这里,您正在同时从多个任务访问 var FilePaths、IEnumerable
。真是个坏主意。 -
仅依赖于 TPL 的默认行为并不总是一个好主意。在许多情况下,需要限制并发级别,这可能就是这种情况。
标签: c# multithreading task-parallel-library file-processing