Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parallel.Foreach maintain collection order?

Is there a way to guarantee order when using Parallel.ForEach()? The collection I am looping over needs to maintain it's order but I was looking for some performance improvement.

like image 782
Brian David Berman Avatar asked Nov 09 '10 16:11

Brian David Berman


2 Answers

In order to retain the order you must try to order the list before passing it to foreach loop since by default the Parallel.Foreach treats the list as unordered.

Example :

Parallel.ForEach(
list.AsParallel().AsOrdered(), 
(listItems) => {<operations that you need to do>});
like image 65
developer_ak Avatar answered Sep 25 '22 13:09

developer_ak


So you have a statement that looks something like this? (based on your comments above).

Parallel.Foreach(myData, ..., (d) =>
{
  StringBuilder sb = new StringBuilder();
  sb.Append(d);
  // WriteLine sb?
});

There are a number of issues with this approach.

  1. Neither Parallel.For or Parallel.ForEach will guarantee that your access to the contents of myData are accessed in any particular order.
  2. if you are a method on Console or a shared StringBuilder to either output the results or build up a complete string then you are probably blocking on a shared resource, effectively serializing parts of your parallel loop.

It's hard to say more without seeing a concrete example of your code. Depending on what you are doing you might be able to use the order preservation AsOrdered() in PLINQ to get where you want.
See this MSDN Resource and Ordered PLINQ ForAll

This will allow you to return an ordered result set, based on the input order but not guarentee the ordering of the actual processing. However if parallel query is blocking on a call within the body you're unlikely to get good performance.

like image 35
Ade Miller Avatar answered Sep 21 '22 13:09

Ade Miller