在向列表添加值时,嵌套并行循环给出的索引在绑定之外

本文关键字:索引 绑定 循环 并行 列表 添加 嵌套 | 更新日期: 2023-09-27 18:22:47

我有一个List-a来用来自数据库的更多值填充List-B,并填充另一个List-C。我使用的是平行循环和普通foreach循环。若我只使用foreach循环,填充List-C大约需要19分钟,但使用并行循环,填充相同的列表只需要3分钟。

但由于某种原因,当将List-B添加到ListC时,会出现错误"索引超出了数组的范围",没有任何信息

List<Variance> Variances = new List<Variance>();
Parallel.ForEach(words, (word) =>
{
     List<wordConfig> configlist = new List<wordConfig>();
     foreach (VariancePopulationConfig value in values)
     {
         VariancePopulationConfig config = new VariancePopulationConfig(Named, Category, Schedule);
         using (SqlConnection con = new SqlConnection(ConnectionString))
         {
             con.Open();
             SqlCommand cmd = new SqlCommand();
             cmd.Connection = con;
             cmd.Parameters.AddWithValue("@word", word);
             cmd.Connection = con;
             cmd.CommandType = CommandType.Text;
             cmd.CommandText = value.SelectQuery;
             returnedvalue = cmd.ExecuteScalar().ToString();
             config.DestinationColOrdinal = value.DestinationColOrdinal;
             config.CurrentOrHistory = value.CurrentOrHistory;
             config.WordValue = returnedvalue.Equals("0") ? string.Empty : returnedvalue;
             config.Word = word;
         }
         configlist.Add(config);
     }
     Variances.Add(new Variance { Word = word, VarianceConfigs = configlist });
});

在向列表添加值时,嵌套并行循环给出的索引在绑定之外

由于要从多个线程向不断增长的列表中添加项目,因此会出现越界错误。一个线程试图扩展数组,而另一个线程正在访问旧的数组。

您可以通过将Parallel.ForEach替换为AsParallelSelect来解决此问题,如下所示:

var Variances = words.AsParallel().Select((word) => {
     List<wordConfig> configlist = new List<wordConfig>();
     foreach (VariancePopulationConfig value in values) {
         VariancePopulationConfig config = new VariancePopulationConfig(Named, Category, Schedule);
         using (SqlConnection con = new SqlConnection(ConnectionString)) {
             con.Open();
             SqlCommand cmd = new SqlCommand();
             cmd.Connection = con;
             cmd.Parameters.AddWithValue("@word", word);
             cmd.Connection = con;
             cmd.CommandType = CommandType.Text;
             cmd.CommandText = value.SelectQuery;
             returnedvalue = cmd.ExecuteScalar().ToString();
             config.DestinationColOrdinal = value.DestinationColOrdinal;
             config.CurrentOrHistory = value.CurrentOrHistory;
             config.WordValue = returnedvalue.Equals("0") ? string.Empty : returnedvalue;
             config.Word = word;
         }
         configlist.Add(config);
     }
     return new Variance { Word = word, VarianceConfigs = configlist };
}).ToList();

没有更多的错误,但有些值是在一些项目的随机位置填充的。

默认情况下,并行选择不会保留原始顺序。可以通过在AsParallel()之后添加.AsOrdered()来解决此问题,但性能可能会降低。