c# - Task Parallel.ForEach loop Error when removing items "Index was outside the bounds of the array. " -


i trying remove items generic list of objects in foreach loop. when doing same thing task parallel library loop getting error. index outside bounds of array.

following code

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)); 

can me in using .net 3.5. task parallel library http://nuget.org/packages/taskparallellibrary

the list class not designed concurrent write (/remove) operations, stated in msdn:

it safe perform multiple read operations on list, issues can occur if collection modified while it’s being read. ensure thread safety, lock collection during read or write operation. enable collection accessed multiple threads reading , writing, must implement own synchronization. collections built-in synchronization, see classes in system.collections.concurrent namespace. inherently thread–safe alternative, see immutablelist class.

for data structures supporting concurrent access, see this linked article.

to clarify why problem arises list class: removeall operation iterate on list instance , match predicate against every contained instance. if predicate evaluates true, index of matched instance used remove entry. if operation performed in concurrent matter, thread may have removed entry, index no longer valid or point instance not matching predicate. operation therefore not threadsafe , not give results expecting. viewing pleasure, given code decompiled method list class:

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; } 

to give more hints: not use parallel code, not without big changes. optimize data structure , simplify statement.

hashset<string> lstsubscriberdidtransaction = ... ...  lstsubscriber.removeall(h => h != null && lstsubscriberdidtransaction.contains(h.msisdn)) 

this should improve performance, more need more insight code.


Comments

Popular posts from this blog

Payment information shows nothing in one page checkout page magento -

tcpdump - How to check if server received packet (acknowledged) -