C# parallel.foreach任务执行的控制顺序

C# parallel.foreach任务执行的控制顺序,c#,parallel-processing,task,parallel.foreach,C#,Parallel Processing,Task,Parallel.foreach,我有一个表名列表(学生、考试、学校) 我使用一个Parallel.ForEach循环来迭代表名,并对每个表进行处理,使用MaxDegreeOfParallelism=8 我的问题是,我的Parallel.ForEach并不总是参与工作窃取。例如,当两个表留待处理时,它们可以一个接一个地处理,而不是并行处理。我正在努力提高性能和吞吐量 我试图通过创建一个自定义的任务调度器来实现这一点,但是,对于我的实现,我需要一个任务的排序列表,其中最简单的任务先排序,这样它们就不会被运行时间较长的表阻塞。我似乎

我有一个表名列表(学生、考试、学校)

我使用一个
Parallel.ForEach
循环来迭代表名,并对每个表进行处理,使用
MaxDegreeOfParallelism=8

我的问题是,我的
Parallel.ForEach
并不总是参与工作窃取。例如,当两个表留待处理时,它们可以一个接一个地处理,而不是并行处理。我正在努力提高性能和吞吐量

我试图通过创建一个自定义的
任务调度器来实现这一点,但是,对于我的实现,我需要一个任务的排序列表,其中最简单的任务先排序,这样它们就不会被运行时间较长的表阻塞。我似乎无法通过对传递给
Parallel.ForEach
list
)的列表进行排序来实现这一点,因为任务由
TaskScheduler
按顺序排队。因此,我需要一种在CustomTaskScheduler中对任务列表进行排序的方法,它基于


我如何控制并行.ForEach将任务传递给要排队的任务调度程序的顺序?

我建议查找。在并行循环上管理线程会有一些开销,因此有一些内置的逻辑来尽量保持较小的开销,同时仍然适当地平衡所有核心之间的工作。这是通过将列表划分为块并调整块大小以达到某个最佳点来实现的

我想,把任务排在最小的第一位,这将不利于双方的平衡。如果平衡是我的目标,我会尝试先安排最大的工作量。我会尝试的另一件事是使用一些恒定的块大小来划分工作项,看看这是否有帮助。或者甚至可以写你自己的分区书

我不确定强制执行死刑是不是一个好主意。由于您不控制操作系统调度程序,因此无法保证任何订购。即使您可以使其更有序,也可能会以吞吐量为代价

另外,如果您花费大量时间优化并行化,您确定其余的代码都优化了吗?

该方法根据源的类型采用两种不同的分区策略。如果源是一个数组或
列表
,则会对其进行静态分区(预先)。如果源代码是一个诚实的\
IEnumerable
,那么它将被动态分区(在运行中)。动态分区具有理想的工作窃取行为,但开销更大。在您的情况下,开销并不重要,因为工作负载的粒度非常低

为了确保分区是动态的,最简单的方法是使用以下方法包装源代码:


➣(该表达式是从中的一条注释中借用的)

为什么不使用任务和WaitAll列表?@SandrisB我不太熟悉,但谷歌告诉我它是用于异步编程的-我需要使任务并行执行,使用WaitAll怎么可能?在这里显示您的代码会很理想。非常感谢,这是非常有洞察力和帮助,在初步检查它的工作像一个魅力!
string[] tableNames;
Parallel.ForEach(Partitioner.Create(tableNames), tableName =>
{
    // Process table
});