Order ConcurrentDictionary. Why is this not working?

We have a C # application that populates tables on sheets in an Excel document.

Tables should be populated in the order in which rows are returned from the database.

The DataFileColData object is defined as a List and contains the rows of the result set. For testing purposes, I use only [0] from the list.

The code segment 1 below does not work. The order of the lines is not preserved in the fact that in the final result the data are displayed out of order, although the numbers themselves are listed in order:

if (DataFileColData[0].Count() > 0)
{
    ConcurrentDictionary<int, DataRow> theRows = new ConcurrentDictionary<int, DataRow>(9, DataFileColData[0].Count());

    Parallel.For(0, DataFileColData[0].Count(), i =>
    {
        // go through each column
        int c = 0;
        try
        {
            foreach (var Col in DataFileColData)
            {
                var cell = Col[i];
                if (cell != null)
                {
                    if (cell.GetType().Name == "JArray") //If Jarray then table compression was used not column compression
                    {
                        if (theRows.TryAdd(i, Dt.NewRow()))
                            theRows[i].ItemArray = JsonConvert.DeserializeObject<object[]>(Col[i].ToString());
                    }
                    else
                    {
                        if (theRows.TryAdd(i, Dt.NewRow()))
                            theRows[i][c] = cell;
                    }
                }
                c++;
            }
        } //try
        catch (Exception e)
        {
            throw new Exception("Exception thrown in \"PublicMethods.cs | RenderExcelFile\" while in foreach loop over DataFileColData: " + e.ToString());
        }

    } //for
    ); //parallel

    //Add the rows to the datatable in their original order
    //(might have gotten skewed from the parallel.for loop)
    for (int x = 0; x < theRows.Count; x++)
        Dt.Rows.Add(theRows[x]);

    //Set the name so it appears nicely in the Excel Name Box dropdown instead of "table1", "table2", etc etc.
    Dt.TableName = ExcelTableSpec.TableTitle + " " + r.TableID;
}

code segment No. 2 below works with line order and data associated with each stored line:

if (DataFileColData[0].Count() > 0)
{
    DataRow[] theRows = new DataRow[DataFileColData[0].Count()];

    Parallel.For(0, DataFileColData[0].Count(), i =>
    {
        DataRow Rw = Dt.NewRow();

        // go through each column
        int c = 0;
        try
        {
            foreach (var Col in DataFileColData)
            {
                var cell = Col[i];
                if (cell != null)
                {
                    if (cell.GetType().Name == "JArray") //If Jarray then table compression was used not column compression
                    {
                        lock (theRows)
                        {
                            theRows[i] = Dt.NewRow();
                            theRows[i].ItemArray = JsonConvert.DeserializeObject<object[]>(Col[i].ToString());
                        }
                    }
                    else
                    {
                        lock (theRows)
                        {
                            theRows[i] = Dt.NewRow();
                            theRows[i][c] = cell;
                        }
                    }
                }
                c++;
            }
        } //try
        catch (Exception e)
        {
            throw new Exception("Exception thrown in \"PublicMethods.cs | RenderExcelFile\" while in foreach loop over DataFileColData: " + e.ToString());
        }

    } //for
    ); //parallel

    //Add the rows to the datatable in their original order
    //(might have gotten skewed from the parallel.for loop)
    Dt = theRows.CopyToDataTable();

    //Set the name so it appears nicely in the Excel Name Box dropdown instead of "table1", "table2", etc etc.
    Dt.TableName = ExcelTableSpec.TableTitle + " " + r.TableID;
}

, . , , "i", ConcurrentDictionary .

- , , , ?

!


@Enigmativity .

MSDN ( ), , , DataTable, MSDN , NewRow().

:

if (DataFileColData[0].Count() > 0)
                {
                    DataRow[] theRows = new DataRow[DataFileColData[0].Count()];

                    Parallel.For(0, DataFileColData[0].Count(), i =>
                    //for (int i = 0; i < DataFileColData[0].Count(); i++)
                    {
                        lock (Dt)
                        {
                            theRows[i] = Dt.NewRow();
                        }

                        // go through each column
                        int c = 0;
                        try
                        {
                            foreach (var Col in DataFileColData)
                            {
                                var cell = Col[i];
                                if (cell != null)
                                {
                                    if (cell.GetType().Name == "JArray") //If Jarray then table compression was used not column compression
                                    {
                                        theRows[i].ItemArray = JsonConvert.DeserializeObject<object[]>(Col[i].ToString());
                                    }
                                    else
                                    {
                                        theRows[i][c] = cell;
                                    }
                                }
                                c += 1;
                            } //foreach
                        } //try
                        catch (Exception e)
                        {
                            throw new Exception("Exception thrown in \"PublicMethods.cs | RenderExcelFile\" while in foreach loop over DataFileColData: " + e.ToString());
                        }

                    } //for
                    ); //parallel

                    //Add the rows to the datatable in their original order
                    //(might have gotten skewed from the parallel.for loop)
                    Dt = theRows.CopyToDataTable();

                    //Set the name so it appears nicely in the Excel Name Box dropdown instead of "table1", "table2", etc etc.
                    Dt.TableName = ExcelTableSpec.TableTitle + " " + r.TableID;

                    //cleanup
                    if (theRows != null)
                        Array.Clear(theRows, 0, theRows.Length);
                    theRows = null;

                } //if (DataFileColData[0].Count() > 0)
+4
1

, ( MSDN).

:

. .

i the ConcurrentDictionary, .


NewRow, NewRow(int record). .

internal DataRow NewRow(int record)
{
  if (-1 == record)
    record = this.NewRecord(-1);
  this.rowBuilder._record = record;
  DataRow row = this.NewRowFromBuilder(this.rowBuilder);
  this.recordManager[record] = row;
  if (this.dataSet != null)
    this.DataSet.OnDataRowCreated(row);
  return row;
}
+2

Source: https://habr.com/ru/post/1607569/


All Articles