You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 14:43:27