C# Parallel For Loop, "Data is incomplete or lost"?

The lists are not threadsafe (different threads accessing the same index at the same time, so then you can experience data loss).

In your case I would take advantage of the fact that you do are not manipulating the number of items being dealt with (fixed length data), and the fact that the indata is also well known, namely a mesh. Therefore use arrays instead in the Parallel loops. This is becaue each thread would then work on guaranteed unique array indexes, and therefore you will not have any such data races as when you use dynamic lists (regular Lists< T > are not thread safe, an absolute no-no in parallel loops, except for reading data, but no writing to list, no-no)

The problem with lists can be illustrated like so:

List.Add(0);         // Say, thread 0 added this
List.Add(0, 1);      // thread 4 added this
List.Add(0, 1, 2);   // thread 2 added this
List.Add(0, 1, 3);   // Ops, thread 3 added at the same time messing up the list

With arrays the indexes intervals are spread out among the threads, and so any one thread will never write to the same location (index) as any other thread

arrary[0| | | ];  // Lets say that thread 0 added this
arrary[0| | |3];  // thread 3 added this
arrary[0|1| |3];  // thread 1 added this
arrary[0|1|2|3];  // thread 2 added this, and 'collisions' thus can't happen.

Notice how you cannot know in which order things happen, and they’re not always even in “order” (they can do things at the same time, and so collisions can occur in dynamic lists).

I know there are advanced concepts out there to deal with things like this, but fixed arrays “cost nothing” to create and fill in (and they are cheap to sum up afterwards in a sequential loop). Arrays allows for quick solutions without diving into any deeper threading philosophy, just use them and off you go.

Also, try to keep everything you write to in the loop as local variable, while variables which you read from doesn’t matter (reading doesn’t cause data races, so reading is no problem inside Parallel loops).

Use arrays. The size is given (var result_array = new double[mesh.Vertices.Count];) and since it will never change size during the loop, therefore nothing bad can happen in the parallel loop (colliding indexes for example). And so on.

// Rolf

1 Like