【发布时间】:2020-01-07 04:12:10
【问题描述】:
我有一个 C# 列表,它将在 Parallel Foreach 中增加价值。现在它总是返回异常 System.IndexOutOfRangeException。当我指向 listTotalCost 时,它有以下消息
源数组不够长。检查 srcIndex 和长度,以及 数组的下界。
它是由线程安全问题和其他问题引起的吗?这是我的代码
List<decimal> listTotalCost = new List<decimal>();
Parallel.ForEach(listDates, dates =>
{
using (DataSet result = calculationMgr.EvaluateFormula(companyID, dates.startDate, dates.endDate, subIndicatorID.Value.ToString(), null, false, null
, (int)Common.Systems.Sustainability.Constants.ApprovalStatuses.Approved
))
{
DataRow dr = result.Tables[0].Rows[0];
//totalPrice = Convert.ToDecimal(dr["Result"]).ToString("#,##0.00");
decimal? temp = Common.Util.TryToConvertToDecimal(dr, "Result");
if (temp != null)
{
//the following line is the error happened
listTotalCost.Add(temp.Value);
}
}
});
【问题讨论】:
-
您正在执行
Parallel循环并在非线程安全上下文中添加值。像这样修改变量时要非常小心。 -
你应该考虑采取thread safe collections之一可能是ConcurrentBag
-
这是可能的原因吗:这两件事都必须以原子方式完成。在您的代码中,可能会发生两个线程在索引 5 处添加一个新元素并且两者都在增加的情况。结果,您可能在索引 5 处有一个元素,但在索引 6 处没有!这种情况不太可能发生,但它可能会发生......我该如何避免它?
-
使用线程安全的集合或锁定对列表的访问。
标签: c# multithreading exception