4

I'm having a little trouble figuring out how to call the Parallel.ForEach with a 2D array of strings:

string[,] board = new string[,]{
        {"A", "B", "C", "D", "E" },
        {"F", "G", "H", "I", "J"},
        {"K", "L", "M", "N", "O"},
        {"0", "1", "2", "3", "4"}};

Parallel.ForEach(board, row =>
    {
        for (int i = 0; i < row.Length; ++i)
        {
            // find all valid sequences
        }
    });

If I don't specify the type explicitly I get the following error:

The type arguments for method 'System.Threading.Tasks.Parallel.ForEach(System.Collections.Generic.IEnumerable, System.Action)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

What's the proper way to specify the type arguments explicitly?

Kiril
  • 39,672
  • 31
  • 167
  • 226

2 Answers2

6

The problem for you is that 2-dimensional arrays do not implement IEnumerable<one-dimensional-array>. (It does implement IEnumerable, but it's an IEnumerable of strings that "flattens" the array.) You can do two things:

  • Change the string[,] to a jagged array-of-arrays, string[][].

  • Implement your own extension method that iterates over a two-dimensional array and turns it into an IEnumerable<one-dimensional-array>.

mqp
  • 70,359
  • 14
  • 95
  • 123
  • @Link: Plus, if performance is enough concern to paralleize this you would want to use jagged arrays anyway because they more efficient to index into. – Brian Gideon Jul 20 '10 at 01:25
  • @Brian Gideon: I think that's a pretty strange thing to say. Parallelization, where appropriate (e.g., in the case of long-running, independent operations), can make a *substantial* change in performance. Converting a multi-dimensional array to a jagged array for performance reasons is what I'd call a micro-optimization. – Dan Tao Jul 20 '10 at 01:41
  • 1
    @Dan: Maybe, but indexing a 2D jagged array is about 3x faster than indexing a multidimensional array. Sure, if indexing is not the dominating factor in the algorithm it buys you little, but if it is then it could wind up being faster than parallelizing the multidimensional array version. Either way it is such as easy change to make and has so few (if any) consequences on code readability or maintainability that it almost seems obvious. Of course any optimization that still keeps you in the same Big-Oh complexity class could qualify as a micro-optimization...`Parallel.For` included. – Brian Gideon Jul 20 '10 at 02:50
3

You should still be able to make this work with a multi-dimensional array, just using Parallel.For instead of Parallel.ForEach:

string[,] board = new string[,] {
    {"A", "B", "C", "D", "E" },
    {"F", "G", "H", "I", "J"},
    {"K", "L", "M", "N", "O"},
    {"0", "1", "2", "3", "4"}
};

int height = board.GetLength(0);
int width = board.GetLength(1);

Parallel.For(0, height, y =>
    {
        for (int x = 0; x < width; ++x)
        {
            string value = board[y, x];
            // do whatever you need to do here
        }
    }
);
Dan Tao
  • 125,917
  • 54
  • 300
  • 447