如何预分配DataGridView行以加速25000条数据加载?
如何预分配DataGridView行空间以提升大量数据加载速度?
我正在将包含25000行数据的文件加载到DataGridView中,加载耗时较长,已为GUI添加每128行更新一次的进度条。请问是否有方法在调用Add方法前预分配行空间,以提升数据行的添加速度?
环境:
- C#(Visual Studio 2017)
- Windows 10
注:我的搜索结果多为向DataGridView添加单行的内容,未找到预分配或预留空间相关方案。
示例代码:
String[] items = file.Split(','); List<string> list = new List<string>(); DataGridView data_table; foreach (String item in items) list.Add(item.Trim()); for (int i = 0; i < list.Count; ++i) { string time_interval_as_string = list[i]; uint time_interval = 0; uint.TryParse(time_interval_as_string, out time_interval); string energy_value_as_string = list[++i]; double energy_value = 0.0; double.TryParse(energy_value_as_string, out energy_value); dataTable.Rows.Add(time_interval, energy_value); }
核心优化方案:通过DataTable预分配行空间
DataGridView本身没有直接的"预分配行"API,但可以借助绑定DataTable的方式实现类似效果,这比直接调用DataGridView.Rows.Add()高效数倍,本质是避免逐行添加时的频繁内存重分配和UI重绘:
- 提前计算总行数并预填充DataTable
先算出数据总行数(你的场景中为list.Count / 2),通过DataTable.Rows.Add()一次性添加对应数量的空行,再批量填充数据,减少内存碎片和操作开销。 - 冻结UI减少重绘消耗
加载数据前暂停DataGridView的布局和自动重绘,完成后再恢复,大幅降低UI线程负担。
优化后的示例代码
// 计算总数据行数 int totalRows = list.Count / 2; // 1. 构建DataTable并预分配行空间 DataTable dt = new DataTable(); dt.Columns.Add("TimeInterval", typeof(uint)); dt.Columns.Add("EnergyValue", typeof(double)); // 批量添加空行,完成预分配 dt.BeginLoadData(); for (int r = 0; r < totalRows; r++) { dt.Rows.Add(); } dt.EndLoadData(); // 2. 冻结DataGridView的UI更新 data_table.SuspendLayout(); data_table.AutoGenerateColumns = false; // 绑定列与DataTable字段(需确保DataGridView已提前创建对应列) data_table.Columns[0].DataPropertyName = "TimeInterval"; data_table.Columns[1].DataPropertyName = "EnergyValue"; data_table.DataSource = dt; // 3. 批量填充数据 for (int i = 0; i < list.Count; i += 2) { uint timeInterval = 0; uint.TryParse(list[i].Trim(), out timeInterval); double energyValue = 0.0; double.TryParse(list[i+1].Trim(), out energyValue); // 直接操作DataTable行,而非DataGridView dt.Rows[i/2]["TimeInterval"] = timeInterval; dt.Rows[i/2]["EnergyValue"] = energyValue; // 保留原有进度条更新逻辑 if ((i/2) % 128 == 0) { // 此处插入你的进度条更新代码 Application.DoEvents(); // 确保UI响应 } } // 恢复UI布局 data_table.ResumeLayout();
额外提速优化点
- 移除冗余中间集合:直接遍历
items数组进行解析,跳过转存到List<string>的步骤,减少内存拷贝 - 高效文件解析:如果是CSV格式文件,使用专门的解析库(如CsvHelper)替代手动Split,处理边缘场景的同时提升解析效率
- 后台线程加载:将数据解析逻辑放到
BackgroundWorker或Task中执行,避免阻塞UI线程,让进度条更新更流畅
内容的提问来源于stack exchange,提问作者Thomas Matthews
相关产品推荐
相关产品推荐

