在我朋友的代码中,他有一个List
:
List<int> listOfIds = new List<int>();
然后,我使用
AddRange()
向其中添加了一个int集合: listOfIds.AddRange(this._employeeList
.Where(r => r.EmployeeID != null)
.Select(r => r.EmployeeID != null ? r.EmployeeID.Value : 0));
但是然后,在日志中,它说:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at System.Collections.Generic.List`1.Enumerator.MoveNext()
at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
at System.Collections.Generic.List`1.InsertRange(Int32 index, IEnumerable`1 collection)
at the method which called the codes above.....
我不太确定为什么会这样。我很确定此错误发生在上面的代码上,但我似乎无法理解为什么会出现
IndexOutofRangeException
的问题。您能帮我指出是什么原因造成的吗?
更新:
我错了。我很抱歉。该方法不使用多线程。但是,另一个称为此方法的方法是使用Parallel.Foreach,这意味着多线程。 _employeeList用作AddRange()的源时,另一个线程可能也在修改它。因此,有关addrange()不是线程安全的答案是合理的。十分感谢大家。
最佳答案
很难说出更具体的想法,但这可能行得通。AddRange
不是线程安全的。尝试使用lock primitives
添加许多项目。宣布:
private static object mutex = new object();
用法
lock(mutex)
{
listOfIds.AddRange( /* code goes here */ )
}
反编译后发现
AddRange
public void AddRange(IEnumerable<T> collection)
{
this.InsertRange(this._size, collection);
}
InsertRange
的内容,可以在堆栈跟踪中看到: ...
ICollection<T> collection1 = collection as ICollection<T>;
if (collection1 != null)
{
...
}
else
{
foreach (T obj in collection)
this.Insert(index++, obj);
}
换句话说-迭代序列并尝试使用递增索引逐项添加。这不应该出错,对吗?
845
中的List.cs
行由dotPeek
反编译。因此,我不会相信堆栈跟踪,除非会看到整个堆栈跟踪。关于c# - LINQ索引超出范围,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14260658/