在向列表添加值时,嵌套并行循环给出的索引在绑定之外
本文关键字:索引 绑定 循环 并行 列表 添加 嵌套 | 更新日期: 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
替换为AsParallel
和Select
来解决此问题,如下所示:
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()
来解决此问题,但性能可能会降低。