Parallel to the loop - problems adding to the list

I'm having some problems with Parallel for loops and adding to List. The problem is that the same code can generate different output at different times. I installed 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, up to 1/10 of the values ​​equal to 9.

After setting up this list, I set up a Parallel for loop that iterates through the list. If the current number is 0, I add the value to the new list. After completing the Parallel for loop, I display the size of the list. The size should be 1000. In most cases, the correct answer is given. However, I saw 3 possible incorrect results:

The message for the argument ArgumentException: Destination array was not long enough. Check destIndex and length, and the array lower bounds. Destination array was not long enough. Check destIndex and length, and the array lower bounds.

What could be causing errors? Is this a .Net error? Is there something I can do to prevent this from happening?

Please try the code for yourself. If you do not receive an error message, try several times. Also note that you probably won't 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(); } } } 
+6
list parallel-processing
source share
1 answer

I expect System.Collections.Generic.List to not be thread safe, which means that if you try Add from two different threads at the same time, everything will go wrong. Oh yes, that is what the docs say.

You can prevent this from happening in several ways:

  • use a collection type that allows you to add streams to streams (there are some new ones in .Net 4.0)
  • lock before adding
  • use streaming local storage for collections and merge them at the end
  • ...

These are very typical problems that you encounter with parallel data code.

+18
source share

All Articles