Q:

Maintaining order of DataTable rows during parallel processing

Following is current piece of code: 
 Parallel.ForEach(dataTable.AsEnumerable(),row => {

     // Code to process the data row to Dictionary<object,object>
     // Unique Column name is the Dictionary Key
     // ConcurrentDictionary is used for thread safety      
     });

Here I use Parallel.ForEach to process the row of a DataTable to an object of Type Dictionary<object,object> final result is of the type List<Dictionary<object,object>>, achieved using intermediate thread safe structure ConcurrentQueue<Dictionary<object,object>>, source of the DataTable sorts the data in a given order, but that is invariably lost during parallel processing. Since the order is important, so I have come up with the following workaround:
Parallel.For(0,RowCount,index => {

  int rowIndex = index;

  // Access the rows using the Index
  // Final structure will be of type ConcurrentDictionary<Custom>, 
  // with the RowIndex assigned based on original index
});

Class Custom
{
  public int RowIndex { get; set; }

  public Dictionary<object,object> DataDictionary {get; set;}
}

Final result of type ConcurrentQueue<Dictionary<Custom>> customObj is processed using following code:
customObj.OrderBy(x=>x.RowIndex).Select(y=>y.DataDictionary).ToList()

Following are my questions:

Is there a better way to achieve the same parallel processing, where I can maintain original order, which is a paramount business requirement
In final solution do I need local variable rowIndex, my understanding is index is part of Parallel loop and would not lead to closure issue

Any pointers ?

A:

You could utilize PLINQ with the ParallelEnumerable.AsOrdered extension method that 

Enables treatment of a data source as if it was ordered, overriding the default of unordered.

In your example you could use it the following way:
var result = dataTable.AsEnumerable().AsParallel().AsOrdered()
                      .Select(/*Process the row to dictionary*/).ToList();

A:

What about this
var items = new ConcurrentDictionary<DataRow, Dictionary<object,object>>;

Parallel.ForEach(dataTable.AsEnumerable(),row => {
    var result = ...; 
    items.Add(row, result);
});

var finalResult = dataTable.Rows.Cast<DataRow>().Select(r => items[r]).ToList());

