C# Parallel - 将项目添加到正在迭代的集合中,或等效?

标签 c# parallel-processing parallel.foreach

现在,我有一个 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));
    

关于C# Parallel - 将项目添加到正在迭代的集合中,或等效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33659380/

相关文章:

c# - 如何用 Java 或 C# 创建快速 MD5 算法

c# - 当所有对象引用被删除时,异步方法会发生什么?

c - MPI 仅从 SELECT 处理器收集

c# - Parallel.ForEach 中的 WebClient.DownloadFile()

c++ - OpenMP 和内存带宽限制

c# - Parallel.foreach 不处理所有项目

azure - 如何并行化 azure worker 角色?

c# - .Net 中嵌入两次的字符串常量?

对 sharepoint 的 C# CAML 查询返回列表中的所有项目(而不是仅匹配查询值的项目)

c# - Parallel.ForEach 在迭代结束时变慢