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?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With