使用ConcurrentBag的并行foreach不起作用

时间:2018-12-18 00:01:31

标签: c# parallel-processing

我被困住了,找不到解决方法。 我有一个长期运行的方法,该方法可以检索对象并将其插入列表中。我正在尝试使其并行以节省一些时间,但项目数量却不相同。

这是我的代码

        var listXls = new List<ReporteXlsPippPrfE>();

        foreach (var records in findItem)
        {

            var item = _plantillaPippBs.GetXlsProformaEpsByCveShcp(records.ftClaveCarteraSHCP);
            if (item != null)
                listXls.Add(item);
        }

        var ConcurrentlistXls = new ConcurrentBag<ReporteXlsPippPrfE>();

        Parallel.ForEach(findItem, records =>
        {
         var item = _plantillaPippBs.GetXlsProformaEpsByCveShcp(records.ftClaveCarteraSHCP);
         if (item != null)
             ConcurrentlistXls.Add(item);

       });

最后,ListXls对象始终检索79个项目,而ConcurrentlistXls对象改变项目的数量。我不知道我是否想念什么。

1 个答案:

答案 0 :(得分:0)

我发现了问题。并非线程安全的方法不是GetXlsProformaEpsByCveShcp。 我要做的不是使用Parallel.ForEach,而是使用List ,然后添加了所有任务并等待所有Task异步完成。 我检查了方法(调用数据库),然后看到过程调用在try catch块内。 同步调用该方法时,永远不会发生异常。但是,当该方法异步执行79次不同的时间时,连接中将出现超时。 因此,仅通过增加SqlCommand对象的TimeOut属性的时间即可解决该问题。

最后,这就是我更改代码的方式

     var asyncBagTask = new List<Task>();
        var ConcurrentlistXls = new ConcurrentBag<ReporteXlsPippPrfE>();

        foreach (var records in findItem)
        {
            asyncBagTask.Add(Task.Run(() =>
            {

                    var item = _plantillaPippBs.GetXlsProformaEpsByCveShcp(records.ftClaveCarteraSHCP);
                    if (item != null)
                    {
                        ConcurrentlistXls.Add(item);
                    }


            }));
        }
      Task.WaitAll(asyncBagTask.ToArray());

感谢所有人。