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:
doubleList.Add(0.0);
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();
}
}
}
I expect that System.Collections.Generic.List is not thread-safe, meaning that if you try to concurrently Add
from two different threads, things will go wrong. Ah yes, it says so in the docs.
You could prevent this from happening in a number of ways:
These are very typical issues you encounter with data parallel code.
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