Ok, so I have a program that works ok. Inside of it there is a for loop that can be parallelized. So I used Parallel.For
to do so. It worked ok one or two times, but the other times there's following exception:
Unspecified error One or more errors occurred
No further information, just this helpful message. Anyone has any idea what might be happening?
Edit: Ok, So I nailed it down to an out of range exception. Turns out I was accessing array elements before initializing them, which seems like a race condition. I had this:
Parallel.For(0, 4, (i, state) =>
{
levelTwoPermutationObjects.Add(new permutationObject());
levelTwoPermutationObjects[i].element = number;
levelTwoPermutationObjects[i].DoThings();
});
Which was making the second and third lines access an element that apparently didn't yet exist. I moved the element initialier out of the parallel loop (so that the array is initialized before being accessed), and now it works.
The iterations were almost independent of each other, except on that Add() part, that obviously depended if there was another element before it or not.
I am risking a shot in the dark:
levelTwoPermutationObjects
is not thread-safe (ie being aList<T>
). You should instead use collections of the namespaceSystem.Collections.Generic.Concurrent
, likeConcurrentBag<T>
(as there's no thread-safe version ofList<T>
), as you are suffering a Race condition (please see the example here) with the.Add
-call (read without write operations are ok within multithreading):Also see the remarks at the MSDN:
If you are not willing or unable to adapt the type of
levelTwoPermutationObjects
you can also utilize alock
-statement like (DANGER DO NOT USE - just for demo):But this will make the
Parallel.For
-call useless. You should in fact adapt your code like (if I interpreted your code correctly):If
.DoThings()
ofpermutationObject
is a long running operation, you should fire off and forget the call with egTask.Run
instead of waiting for the result to proceed with the.Add
-call.Otherwise you can transform your processing chain into a seeding-process that adds elements to the collection (which should be a short running operation) and a processing-process (where each iteration can be a long running operation) to avoid a Race condition by only doing reads after sequential writes, like: