C# 删除项目时出现Task Parallel.ForEach循环错误";索引超出了数组的边界&引用;
我试图删除foreach循环中对象的通用列表中的项。当我对任务并行库循环做同样的事情时,我得到了错误。 索引超出了数组的边界。 下面是我的代码C# 删除项目时出现Task Parallel.ForEach循环错误";索引超出了数组的边界&引用;,c#,task-parallel-library,C#,Task Parallel Library,我试图删除foreach循环中对象的通用列表中的项。当我对任务并行库循环做同样的事情时,我得到了错误。 索引超出了数组的边界。 下面是我的代码 List<string> lstSubscriberDidTransaction = ...; // Initialization var lstSubscriber = JsonConvert.DeserializeObject<List<SubscriberInfoShortenObject>>(somestrin
List<string> lstSubscriberDidTransaction = ...; // Initialization
var lstSubscriber = JsonConvert.DeserializeObject<List<SubscriberInfoShortenObject>>(somestring);
foreach (string strId in lstSubscriberDidTransaction)
{
lstSubscriber.RemoveAll(h => h != null && h.Msisdn == strId);
}
//Parallel.ForEach(lstSubscriberDidTransaction, msisdn => lstSubscriber.RemoveAll(h => h != null && h.Msisdn == msisdn));
List lstSubscriberDidTransaction=…;//初始化
var lstSubscriber=JsonConvert.DeserializeObject(somestring);
foreach(lstSubscriberDidTransaction中的字符串strId)
{
lstSubscriber.RemoveAll(h=>h!=null&&h.Msisdn==strId);
}
//Parallel.ForEach(lstSubscriberDidTransaction,msisdn=>lstSubscriber.RemoveAll(h=>h!=null&&h.msisdn==msisdn));
有人能帮我吗
我正在使用.NET3.5。对于具有的任务并行库,
列表
类不是为并发写入(/remove)操作而设计的,如中所述:
对一个列表执行多个读取操作是安全的,但是
如果在读取集合时对其进行修改,则可能会出现问题。
为确保线程安全,请在读取或写入期间锁定集合
活动使集合能够由多个线程访问
对于读写,您必须实现自己的同步。
有关内置同步的集合,请参见中的类
System.Collections.Concurrent命名空间。对于固有的线程安全性
或者,请参见ImmutableList类
有关支持并发访问的数据结构,请参阅
要澄清问题产生于列表
类的原因,请执行以下操作:
RemoveAll
操作将在列表实例上迭代,并根据包含的每个实例匹配谓词。如果谓词的计算结果为true,则匹配实例的索引将用于删除条目。如果操作是在并发事件中执行的,那么另一个线程可能已经删除了另一个条目,因此索引不再有效,或者将指向与谓词不匹配的另一个实例。因此,该操作不是线程安全的,不会给出您期望的结果。
为了便于查看,给定的代码是列表
类中的反编译方法:
public int RemoveAll(Predicate<T> match)
{
if (match == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
int index1 = 0;
while (index1 < this._size && !match(this._items[index1]))
++index1;
if (index1 >= this._size)
return 0;
int index2 = index1 + 1;
while (index2 < this._size)
{
while (index2 < this._size && match(this._items[index2]))
++index2;
if (index2 < this._size)
this._items[index1++] = this._items[index2++];
}
Array.Clear((Array) this._items, index1, this._size - index1);
int num = this._size - index1;
this._size = index1;
++this._version;
return num;
}
public int RemoveAll(谓词匹配)
{
if(match==null)
ThrowHelper.ThrowArgumentNullException(argument.match除外);
int index1=0;
而(index1=该尺寸)
返回0;
int index2=index1+1;
而(index2<此尺寸)
{
而(index2
要提供更多提示,请执行以下操作: 不要使用并行代码,因为如果没有大的更改,它将不会帮助您。优化查找数据结构并简化语句
HashSet<string> lstSubscriberDidTransaction = ...
...
lstSubscriber.RemoveAll(h => h != null && lstSubscriberDidTransaction.Contains(h.Msisdn))
HashSet lstSubscriberDidTransaction=。。。
...
lstSubscriber.RemoveAll(h=>h!=null&&lstSubscriberDidTransaction.Contains(h.Msisdn))
这将提高性能,要获得更多帮助,我们需要对您的代码有更多的了解。您可以尝试
Parallel.ForEach(lstSubscriberDidTransaction.ToArray())
他似乎在迭代两个不同的源。lstSubscriberDidTransaction
和lstSubscriber
RemoveAll
也会迭代列表,所以lstSubscriber
他是以并行方式读写的。@KamranShahid不要使用并行代码,因为它对您的情况没有帮助。只需调用lstSubscriber.RemoveAll(h=>h!=null&&lstSubscriberDidTransaction.Contains(h.Msisdn))
@KamranShahid优化数据结构,查看我的更新答案。问题查看了1000多次,但有人对其进行了负面标记。我希望当有人否决投票时,应该有必要的评论,以便提问者能够了解其中的错误。