user2119777
user2119777

Reputation: 77

Parallel For losing values when looping

I'm facing a strange issue that I can't explain and I would like to know if some of you have the answer I'm lacking.

I have a small test app for testing multithreading modifications I'm making to a much larger code. In this app I've set up two functions, one that does a loop sequentially and one that uses the Task.Parallel.For . The two of them print out the time and final elements generated. What I'm seeing is that the function that executes the Parallel.For is generating less items than the sequential loop and this is huge problem for the real app(it's messing with some final results). So, my question is if someone has any idea why this could be happening and if so, if there's anyway to fix it.

Here is the code for the function that uses the parallel.for in my test app:

static bool[] values = new bool[52];

static List<int[]> combinations = new List<int[]>();

static void ParallelLoop()
{
    combinations.Clear();
    Parallel.For(0, 48, i =>
    {
        if (values[i])
        {
            for (int j = i + 1; j < 49; j++)
                if (values[j])
                {

                    for (int k = j + 1; k < 50; k++)
                    {

                        if (values[k])
                        {

                            for (int l = k + 1; l < 51; l++)
                            {
                                if (values[l])
                                {
                                    for (int m = l + 1; m < 52; m++)
                                    {
                                        if (values[m])
                                        {
                                            int[] combination = { i, j, k, l, m };
                                            combinations.Add(combination);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
        }

    }); // Parallel.For
}

And here is the app output:

Executing sequential loop...
Number of elements generated: 1,712,304
Executing parallel loop...
Number of elements generated: 1,464,871

Thanks in advance and if you need some clarifications I'll do my best to explain in further detail.

Upvotes: 3

Views: 192

Answers (1)

ken2k
ken2k

Reputation: 48985

You can't just add items in your list by multiple threads at the same time without any synchronization mechanism. List<T>.Add() actually does some none-trivial internal stuff (buffers...etc) so adding an item is not an atomic thread-safe operation.

Either:

  • Provide a way to synchronize your writes
  • Use a collection that supports concurrent writes (see System.Collections.Concurrent namespace)
  • Don't use multi-threading at all

Upvotes: 8

Related Questions