DataTable删除行耗时极长,如何优化该操作?
解决方案
1. 临时解绑DataGridView数据源(最关键)
DataGridView与DataTable绑定后,每删除一行都会触发UI端的RowRemoved、ListChanged等事件,哪怕调用SuspendLayout()也无法完全规避这些事件的开销(数据绑定的事件机制独立于布局逻辑)。临时解绑数据源能彻底切断UI与数据变更的联动,这是提速的核心:
var dataTable = _dataSetDataGridView.Tables[tableInfo.Id]; var grid = _dataSetDataGridView; var originalSource = grid.DataSource; // 临时解绑数据源 grid.DataSource = null; // 预处理Keys为HashSet优化查询 var cleanedKeys = keys.Select(v => Regex.Replace(v, @"^'|'$", "")).ToHashSet(); var rowsToDelete = dataTable.Rows.Cast<DataRow>() .Where(row => cleanedKeys.Contains(row[id].ToString())) .ToList(); // 执行删除 foreach (var row in rowsToDelete) row.Delete(); dataTable.AcceptChanges(); // 重新绑定数据源 grid.DataSource = originalSource;
2. 关闭DataTable事件通知辅助提速
批量操作时关闭DataTable的ListChanged事件触发,能减少内部事件处理的额外开销,配合解绑数据源效果更明显:
dataTable.SuppressListChangedEvents = true; try { foreach (var row in rowsToDelete) row.Delete(); dataTable.AcceptChanges(); } finally { // 必须恢复事件通知,否则后续数据变更无法同步到UI dataTable.SuppressListChangedEvents = false; }
3. 直接移除行(替代Delete+AcceptChanges)
如果业务不需要先标记删除状态(比如无需区分Deleted行),可以直接调用Rows.Remove()跳过标记步骤,省去AcceptChanges()的额外开销:
// Remove会直接从DataTable中移除行,无需后续AcceptChanges foreach (var row in rowsToDelete) dataTable.Rows.Remove(row);
内容的提问来源于stack exchange,提问作者Lemmes
相关产品推荐
相关产品推荐

