D J*_*D J 2 .net c# multithreading task-parallel-library
我有一个集合,其中包含要处理的元素,最多只能处理四个元素.在运行时,所有进程一起启动,所有进程都处于等待状态.一次只处理四个元素.
问题是随机选择处理元素,因为所有线程都在等待资源获得释放.意味着第一个元素可以是集合中的最后一个元素.
但是,我需要按照它们在集合中的顺序处理元素.
请告诉我如何实现这一目标?
我正在使用TPL和C#4.0
对于并行性,总是存在定义"按顺序"意味着什么的问题.假设您有100个项目的集合.按"按顺序"按顺序处理它们(按照您的要求)可能意味着:
松散排序:使用4个线程并按原始集合的顺序发出任务.
在这种情况下,您可以使用:
ParallelOptions po = new ParallelOptions() { MaxDegreeOfParallelism = 4 };
Parallel.ForEach(list.AsParallel().AsOrdered(), po,
(item) =>
{
// code
});
Run Code Online (Sandbox Code Playgroud)
在不平衡任务的情况下,这将很快失去原始排序,因为一些线程可能在重任务上落后,但任务将按顺序分配.
严格的排序:按顺序处理它们,如下所示:
0 1 2 3
4 tasks
_____________________________
barrier
4 5 6 7
4 tasks
_____________________________
barrier
etc.
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您可以使用屏障:
Barrier b = new Barrier(4);
ParallelOptions po = new ParallelOptions() { MaxDegreeOfParallelism = 4 };
Parallel.ForEach(list.AsParallel().AsOrdered(), po,
(item) =>
{
// code
b.SignalAndWait();
});
Run Code Online (Sandbox Code Playgroud)
虽然您必须确保任务数是4的倍数,否则在最后一次迭代时不会发出屏障信号.
处理单个任务中的4个项目:您可以创建一个封装原始列表的4个项目的任务对象,然后Parallel.ForEach
像第一个案例那样执行简单操作(即每个线程将按顺序处理4个项目作为单个任务的一部分).这将按顺序以4个为一组发出任务,但如果任务花费的时间过长,则可能会导致某些线程滞后.