C#并行-将项目添加到要迭代的集合中,还是等效?
作者:互联网
现在,我有一个C#程序,该程序可以重复执行以下步骤:
>从数据库中获取当前任务列表
>使用Parallel.ForEach(),完成每个任务
但是,其中一些任务的运行时间很长.这会延迟其他未完成任务的处理,因为我们仅在程序开始时寻找新任务.
现在,我知道不可能修改要迭代的集合(对吗?),但是C#Parallel框架中是否存在某些等效功能,可以使我向列表添加工作,同时还可以处理列表中的项目?
解决方法:
一般来说,您是正确的,不允许在迭代时修改集合.但是您可以使用其他方法:
>使用ActionBlock<T>
from TPL Dataflow.代码可能类似于:
var actionBlock = new ActionBlock<MyTask>(
task => DoWorkForTask(task),
new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded });
while (true)
{
var tasks = GrabCurrentListOfTasks();
foreach (var task in tasks)
{
actionBlock.Post(task);
await Task.Delay(someShortDelay);
// or use Thread.Sleep() if you don't want to use async
}
}
>使用BlockingCollection<T>
(与GetConsumingParititioner()
from ParallelExtensionsExtras一起使用),可以在使用其中的项目时对其进行修改,以使其与Parallel.ForEach()一起使用:
var collection = new BlockingCollection<MyTask>();
Task.Run(async () =>
{
while (true)
{
var tasks = GrabCurrentListOfTasks();
foreach (var task in tasks)
{
collection.Add(task);
await Task.Delay(someShortDelay);
}
}
});
Parallel.ForEach(collection.GetConsumingPartitioner(), task => DoWorkForTask(task));
标签:parallel-foreach,parallel-processing,c 来源: https://codeday.me/bug/20191119/2036268.html