Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we add new elements to a list using Parallel.ForEach()?

My code does very simple stuff

list already has elements. I have approximately 25000 elements (and I'm expecting to have more) in the list and each element is small (DateTime).

List<DateTime> newList = new List<DateTime>();
Parallel.ForEach(list, l => newlist.Add(new DateTime(l.Ticks + 5000)));

i.e, based on each element, I'm creating new elements and adding them to a different list. But, this doesn't seem to be a good programming approach. I hit this exceptions some times, but not everytime.

IndexOutOfRangeException : {"Index was outside the bounds of the array."}

Can we add elements to a list using Parallel.ForEach()? If yes, why do I hit the error? If no, why?

like image 623
clewaks Avatar asked Dec 03 '22 04:12

clewaks


2 Answers

What you would really want in this situation is more like this:

newlist = list.AsParallel().Select(l => new DateTime(l.Ticks + 5000)).ToList();

Although you should measure the performance to see if this situation even benefits from parallelization.

like image 91
Gabe Avatar answered Feb 17 '23 01:02

Gabe


Try a thread local variable with a final result that adds all thread local variables to the newList as such...

Parallel.ForEach(list, () => DateTime.MinValue, (l, state, date) =>
{
    date = new DateTime(l.Ticks+5000);
    return date;
},
finalresult =>
{
   lock (newList)
   {
       newList.Add(finalresult);
   }
});

The first param is your old list the second Param is the initial value of each thread (I just initialized to datetime min). the third param block is as follows- the l is the same as in your code; the state is a Paralleloption object of which you can exit out of parallel loop if you choose; the last is the stand in variable that represents the thread local variable. The finalresult param represents the end result of each thread local variable and is called for each thread - it is there you can place a lock of the newList and add to the newList shared variable. In theory this works. I have used similar coding in my own code. Hope this helps you or someone else.

like image 32
Pleasantlydone Avatar answered Feb 17 '23 00:02

Pleasantlydone