C#parallel.foreach饿死数据

时间:2018-03-09 00:04:32

标签: c# multithreading parallel.foreach

我的应用程序处理数百万条大小不一的数据。小物体可以快速处理,而其他物体可能需要15分钟。

我目前的代码:

List<QueueRecords> queueRecords= Get500QueueRecords();
bool morefiles=true;
while(morefiles)
{
    Parallel.ForEach(
    queueRecords,parallelOptions,(record,loopstate)=>
    {
    //dowork
    }
    queueRecords = Get500QueueRecords();
    if(queueRecords.Count() == 0)
    {
    morefiles = false;
    }
}

这个问题是,很多时候我会在一个线程执行长时间运行任务的同时仍然需要处理大量数据。

我应该考虑采用哪种模式来解决此问题?

1 个答案:

答案 0 :(得分:1)

问题:    1)Get500QueueRecords也可能需要一些时间来执行,在此期间您不进行任何处理;    2)如果一组中的最后一条记录需要15分钟,那么您只需要处理一条记录,因为ParallelForEach将等待它完成。

你真的应该看看TPL DataFlow(https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/dataflow-task-parallel-library)或至少创建一个读者任务,将数据泵入BlockingCollection<T>,然后启动多个读取器任务,从阻塞集合中提取直到消耗完。

在它们之间使用生产者和有限大小BlockingCollection<T>的消费者允许您控制(i)从阅读器任务缓冲的项目数量和(ii)您消耗它的任务数量。