I'm working on an app for my company, and the users have the ability to load a lot of rows into a DataGridView. That hasn't been a problem, but when the user selects more than ~20 rows to delete, the app hangs and becomes unresponsive. While there are methods to just take the specific form out and put the operation on a background worker thread, I couldn't imagine what the problem could possibly be. What I was doing is getting an array of rows from the DataTable.Select() method, and then I would loop through the results and do the Remove() method of the DataTable. I had a key on this DataTable, so I tried dropping that, but it wasn't working. I did a few Google searches, but couldn't find the answer. I'm usually pretty good at searching Google, but this time, it was a desert out there.
The SolutionIt occured to me that the DataTable.Clear() method is pretty fast, and adding rows is pretty quick, so the solution is to create a new DataTable, add the rows to keep in that DataTable, clear out the original table, and then call Merge() on it to bring in the kept rows.
DataTable myDataTable; //this would actually be a strongly typed DataSet in my case. private void Example() { DataRow[] dataRows = myDataTable.Select("Selected=true"); //turn off the event for a bit myDataTable.RowDeleted -= myDataTable_RowDeleted; if (dataRows.Length == myDataTable.Rows.Count) { myDataTable.Clear(); } else if (dataRows.Length > 20) { DataTable myNewDataTable = new DataTable(); dataRows = myDataTable.Select("Selected=false"); DataRow newRow; foreach (DataRow row in dataRows) { newRow = myNewDataTable.NewRow(); newRow.Col1 = row.Col1; newRow.Col2 = row.Col2; myNewDataTable.Rows.Add(newRow); } myDataTable.Clear(); myDataTable.Merge(myNewDataTable); } else { //it's ok to loop through 20 or fewer foreach (DataRow selectedRow in dataRows) myDataTable.Rows.Remove(selectedRow); } //turn the event back on myDataTable.RowDeleted += myDataTable_RowDeleted; }