Search code examples
c#while-loopparallel-processingparallel.foreach

Infinite parallel while loop


I need to call the same method in parallel in C# (MaxDegreeOfParallelism = Environment.ProcessorCount). The method returns a sequence of numbers. If this sequence fulfills certain criteria - I need to do the following

  1. Stop all threads
  2. Return the sequence
  3. Return how many time the method has been called in total

I have the below code - but I have some problems figuring out what to write in my GetValidSequenze method where I have written: //WHAT TO DO HERE??

Any ideas? Am I doing something wrong?

public class Example3
{
    public delegate int Randomizer(int minValue, int maxValue);

    private Randomizer rand;

    public Example3(Randomizer randomizer)
    {
        rand = randomizer;

    }
    private IEnumerable<bool> Infinite()
    {
        while (true)
        {
            yield return true;
        }
    }

    public int[][] GetValidSequenze(int minValue, int maxValue, int rows,
        int columns, int sn, ref int counter)
    {
        ParallelOptions op = new ParallelOptions();
        op.MaxDegreeOfParallelism = Environment.ProcessorCount;
        int[][] result;

        Parallel.ForEach(Infinite(), parallelOptions: op //WHAT TO DO HERE?? =>
        {
            int[][] tempRes;
            while (!(tempRes = GetSequenze(minValue, maxValue, rows, columns))
                .All(o => o.Contains(sn)))
            {
                Interlocked.Increment(ref counter);
            }
            loopState.Stop();
            result = tempRes;
        });

        return result;
    }

    public int[][] GetSequenze(int minValue, int maxValue, int rows, int columns)
    {
        int[][] lot = new int[rows][];
        for (int i = 0; i < rows; i++)
        {
            int[] column = new int[columns];
            for (int j = 0; j < columns; j++)
            {
                while (true)
                {
                    int tempNo = rand(0, 40);
                    if (!column.Contains(tempNo))
                    {
                        column[j] = tempNo;
                        break;
                    }
                }
            }
            lot[i] = column;
        }
        return lot;
    }
}

Solution

  • Your code doesn't compile. Below is version of the GetValidSequenze method that compiles:

    public int[][] GetValidSequenze(int minValue, int maxValue, int rows,
        int columns, int sn, ref int counter)
    {
        int localCounter = counter;
        ParallelOptions op = new ParallelOptions();
        op.MaxDegreeOfParallelism = Environment.ProcessorCount;
        int[][] result = default;
    
        Parallel.ForEach(Infinite(), parallelOptions: op, (_, loopState) =>
        {
            int[][] tempRes;
            while (!(tempRes = GetSequenze(minValue, maxValue, rows, columns))
                .All(o => o.Contains(sn)))
            {
                Interlocked.Increment(ref localCounter);
            }
            loopState.Stop();
            result = tempRes;
        });
    
        counter = localCounter;
        return result;
    }
    

    Chances are that whatever you want to do, could be done more efficiently by improving the algorithm, than by parallelizing a probably inefficient algorithm.