none
Parallel for loop .....Deleting Row in datatable not working RRS feed

  • Question

  • Parallel for loop .....Deleting Row in data table not working,

    Parallel.For((long)0, datatable.Rows.Count, rowi =>
                 {
                     lock (datatable)
                     {
                         row1 = datatable.Rows[(int)rowi];
    
                         if (somelogic)
                         {
                             row1.Delete();
                         }
    
                     }
                 });

                        
    Wednesday, November 30, 2016 9:23 AM

Answers

  • Use this as inspiration, maybe:

                int i;
                DataTable datatable = new DataTable();
    
                Parallel.ForEach<DataRow, bool>(datatable.AsEnumerable(), // source collection
                                () => false, // method to initialize the local variable
                                (row1, loop, result) => // method invoked by the loop on each iteration
                                         {
                                             if (true) // somelogic
                                             {
                                                 row1.Delete();
                                                 return true;
                                             }
                                         },
                                // Method to be executed when each partition has completed.
                                (finalResult) =>  i = 0
                                );


    My Technet Articles

    If you like this or another reply, vote it up!
    If you think this or another reply answers the original question, mark it or propose it as an answer.


    Mauricio Feijo
    www.mauriciofeijo.com

    • Proposed as answer by DotNet WangModerator Monday, December 5, 2016 7:51 AM
    • Marked as answer by ID GO Monday, December 5, 2016 1:42 PM
    Wednesday, November 30, 2016 2:26 PM

All replies

  • Not sure where row.Delete() is threadsafe or not, but you definitely can't delete them by row number like that because when you delete a row, the row count will obviously change!

    If you have 5 rows and delete row 3 then rows 0 and 1 will remain as before, but what were previously rows 3 and 4 will now become rows 2 and 3 (for a total count of 4 rows)

    Wednesday, November 30, 2016 9:46 AM
  • Hi ID GO,

    The exception you are getting IndexOutofRange because when your starts the loop it counts the total number of Rows in datatable then deletion starts but there is no logic to decrement that count after deleting a row. Suppose you have 10 rows in your datatable. When delete starts it will delete from beginning of the row so, now the row count is 9 but your loop still has total count 10 because it doesn't decrement its count so, when it reaches to delete the last 1 row that time loop count still has 10 and will continue because there is no row left in datatable you will get an exception of Index out of range.


    Thanks,
    Sabah Shariq

    [If a post helps to resolve your issue, please click the "Mark as Answer" of that post or click Answered "Vote as helpful" button of that post. By marking a post as Answered or Helpful, you help others find the answer faster. ]

    Wednesday, November 30, 2016 10:27 AM
    Moderator

  • for (int i = dt.Rows.Count - 1; i >= 0; i--) { DataRow row = dt.Rows(i); if (!string.IsNullOrEmpty(row[10].ToString())) { row.Delete(); } }

    dt.AcceptChanges()

    Above Code is Working Fine.....But I need Parallel for loop
    • Edited by ID GO Wednesday, November 30, 2016 10:32 AM
    Wednesday, November 30, 2016 10:31 AM
  • Again, it is because you cannot refer to rows by number when the count is changing within the loop itself (your reverse loop works because you are deleting all rows from the highest to the lowest so the count going down doesn't affect the 'row i' that gets deleted).

    You could try putting all rows into a DataRow array first, and then do a parallel for loop around that DataRow array (whose count will not change). Although the fact that you must do an initial loop first may counteract any modest performance gain from the parallel loop.

    Wednesday, November 30, 2016 10:37 AM
  • Hi ID GO,

    Above code is working because for loop is decrementing every time it executes. you need to add that decrements logic in your parallel loop.


    Thanks,
    Sabah Shariq

    [If a post helps to resolve your issue, please click the "Mark as Answer" of that post or click Answered "Vote as helpful" button of that post. By marking a post as Answered or Helpful, you help others find the answer faster. ]

    Wednesday, November 30, 2016 10:37 AM
    Moderator
  • Is there anyway I can Solve This
    • Edited by ID GO Wednesday, November 30, 2016 1:47 PM
    Wednesday, November 30, 2016 1:43 PM
  • Use this as inspiration, maybe:

                int i;
                DataTable datatable = new DataTable();
    
                Parallel.ForEach<DataRow, bool>(datatable.AsEnumerable(), // source collection
                                () => false, // method to initialize the local variable
                                (row1, loop, result) => // method invoked by the loop on each iteration
                                         {
                                             if (true) // somelogic
                                             {
                                                 row1.Delete();
                                                 return true;
                                             }
                                         },
                                // Method to be executed when each partition has completed.
                                (finalResult) =>  i = 0
                                );


    My Technet Articles

    If you like this or another reply, vote it up!
    If you think this or another reply answers the original question, mark it or propose it as an answer.


    Mauricio Feijo
    www.mauriciofeijo.com

    • Proposed as answer by DotNet WangModerator Monday, December 5, 2016 7:51 AM
    • Marked as answer by ID GO Monday, December 5, 2016 1:42 PM
    Wednesday, November 30, 2016 2:26 PM
  • Is there anyway I can Solve This

    Yes: Do not do bulk deletion this way.
    Use Delete with proper conditions in the DBMS.

    Database operations are the prime example of operations you can only make slower and prone to race conditions by paralleising them.

    One extra thread to maybe not lock up the GUI? Sure. Multithreading? Forget it.


    Remember to mark helpfull answers as helpfull and close threads by marking answers.

    Wednesday, November 30, 2016 7:10 PM