今天我来这里是为了讨论一个常见的DataGridView的数据加载问题及其解决方法,希望对大家有所帮助。
正如标题所示,我们通常有一个需要在 DataGridView 控件中显示的大型数据集,并且数据集越大,在控件中加载行所需的时间就越长,并且 UI 可能会挂起。
在这篇文章里将讨论 IT 人员采用的方法,并创建一个基准。此外,我最终会得到一个非常实用的解决方案,它几乎适用于所有 .Net 框架。
注意:在用于测试的数据表中有超过 100,000 行,这是用来演示的查询:
Dim query as string = “select top 10000 * from dbo.Logging where id > " & dt.Rows.Count
这里:使用`dt.Rows.Count`作为过滤器来获取接下来的 10k 行。如果需要,在第二次运行时使用。所有情况都使用相同的查询
现在让我们仔细看看细节:
解决方案 1:使用For循环加载行(较慢的方法)
Private Sub LoadMoreRows()
Dim dt As DataTable = fillDataTable(CType(dgv.DataSource, DataTable))
If (dgv.Columns.Count = 0) Then
For col As Integer = 0 To dt.Columns.Count – 1
dgv.Columns.Add(New DataGridViewTextBoxColumn()
With {.HeaderText = dt.Columns(col).ColumnName})
Next
End If
For row As Integer = 0 To dt.Rows.Count – 1
dgv.Rows.Add(dt.Rows(row).ItemArray)
Next
End Sub
第一次运行: (约 7 秒)
开始时间: 03:39:31.48069
结束时间 : 03:39:38.51909
第二次运行: (约 8 秒)
开始时间: 03:39:50.13576
结束时间 : 03:39:58.86226
结论:不应使用 此方法,因为它会导致 UI 卡住。我们可以结合使用BackgroundWorker类来解决 UI 卡住问题。但是为什么呢?如果我们还有其他选择呢?
因此,请考虑另一种选择。
解决方案2:设置DataSource属性:(稍快一些)
Private Sub LoadMoreRows()
Dim dt As DataTable = fillDataTable(CType(dgv.DataSource, DataTable))
dgv.DataSource = dt
End Sub
第一次运行:(约4 秒)
开始时间: 03:54:17.50337
结束时间 : 03:54:21.70761
第二次运行:(约 0 秒)
开始时间: 03:54:34.16732
结束时间 : 03:54:34.39033
设置数据源属性是一种更快的技术,因为它不是每次都向控件的行集合中添加一行,而是一次性绑定整个数据。
结论:因此它可以被使用,并且具有可接受的结果。
您是否想象过如果数据源有大量行会怎样?
是的,假设数据源有 100,000 行,上述解决方案将一次加载并绑定 100,000 行。
第一次运行:(约 2 秒)
开始时间: 04:02:06.28518
结束时间 : 04:02:08.72932
结论:设置DataSource属性可以快速获取结果集,但如果数据行数较多,一次性加载整个数据集则不理想。加载时间会随着行数的增加而增加(例如,一个表有 10 万行,需要一次性加载所有数据)。我建议继续使用下一个解决方案。
解决方案 3:读取并合并数据源:(快速且优化 - 推荐)
该解决方案背后的想法是分块获取数据,并将该块合并到已检索到的数据集中。
以下是源代码:
Private Sub LoadMoreRows()
Dim dt As DataTable = fillDataTable(CType(dgv.DataSource, DataTable))
If dgv.DataSource IsNot Nothing Then
CType(dgv.DataSource, DataTable).Merge(dt)
Else
dgv.DataSource = dt
End If
‘ Scroll to last row (Optional)
dgv.FirstDisplayedScrollingRowIndex = CType(dgv.DataSource, DataTable).Rows.Count
End Sub
第一次运行: (大约 1 秒)
开始时间: 04:31:12.71807
结束时间 : 04:31:13.13209
第二次运行: (约 1 秒)
开始时间: 04:31:17.18933
结束时间 : 04:31:17.67535
第三次运行: (约 1 秒)
开始时间: 04:31:25.72281
结束时间 : 04:31:26.30485
第四次运行: (大约 1 秒)
开始时间: 04:31:31.73316
结束时间 : 04:31:32.35919
您是否注意到datagridview中有40,000 行(每次运行取 10,000 行)并且获取时间总是相同的?
结论:以块的形式检索数据然后使用 MERGE与datagridview控件绑定是明智的,因为通过这种方式,您可以获得接下来的 N 条记录而没有任何开销,并且只需不到一秒钟。
希望这篇文章对你有用,并希望以后能用到。如果你有任何意见或想法,希望它能更实用,请随时提出。等待您的反馈!
如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。