I am having some issues involving Parallel for loops and adding to a List. The problem is, the same code may generate different output at different times. I have set up some test code below. In this code, I create a List of 10,000 int values. 1/10th of the values will be 0, 1/10th of the values will be 1, all the way up to 1/10th of the values being 9.
After setting up this List, I setup a Parallel for loop that iterates through the list. If the current number is 0, I add a value to a new List. After the Parallel for loop completes, I output the size of the list. The size should always be 1,000. Most of the time, the correct answer is given. However, I have seen 3 possible incorrect outcomes occur:
The size of the list is less than 1,000
An IndexOutOfRangeException occurs @ doubleList.Add(0.0);
An ArgumentException occurs @ doubleList.Add(0.0);
The message for the ArgumentException given was: Destination array was not long enough. Check destIndex and length, and the array's lower bounds.
What could be causing the errors? Is this a .Net bug? Is there something I can do to prevent this from happening?
Please try the code for yourself. If you do not get an error, try it a few times. Please also note that you probably will not see any errors using a single-core machine.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ParallelTest
{
class Program
{
static void Main(string[] args)
{
List<int> intList = new List<int>();
List<double> doubleList = new List<double>();
for (int i = 0; i < 250; i++)
{
intList.Clear();
doubleList.Clear();
for (int j = 0; j < 10000; j++)
{
intList.Add(j % 10);
}
Parallel.For(0, intList.Count, j =>
{
if (intList[j] == 0)
{
doubleList.Add(0.0);
}
});
if (doubleList.Count != 1000)
{
Console.WriteLine("On iteration " + i + ": List size = " + doubleList.Count);
}
}
Console.WriteLine("\nPress any key to exit.");
Console.ReadKey();
}
}
}