在您的代码中,这一行将占用大部分处理时间:
SDA.Fill(DTGdataTable);
所以我认为最重要的是在执行过程中跟踪进度。为此,您首先需要知道您期望的行数。SQLDataAdapter 无法提供此信息,因此您需要先运行额外的 COUNT(*) 查询才能获取此数字。然后,您可以将其用作 ProgressBar 上的最大值。
我的实际加载代码基于 Michael Hofmeiers 解决方案,但不是在选取框模式下使用 ProgressBar,而是使用来自 Timer Control 的真实进度数据提供给它。因此,在您的表单上,添加一个 Timer 控件(在我的示例中名为 progressTimer),将其 Interval 设置为 100 毫秒,并将 Enabled 设置为 false。然后代码变为:
private DataTable table = null;
private void buttonLoad_Click(object sender, EventArgs e)
{
// TODO: Select the row count here and assign it to progressBar.Maximum
progressBar.Visible = true;
System.Threading.Thread thread =
new System.Threading.Thread(new System.Threading.ThreadStart(loadTable));
thread.Start();
progressTimer.Enabled = true;
}
private void loadTable()
{
// Load your Table...
this.table = new DataTable();
SqlDataAdapter SDA = new SqlDataAdapter();
SDA.Fill(table);
setDataSource(table);
}
internal delegate void SetDataSourceDelegate(DataTable table);
private void setDataSource(DataTable table)
{
// Invoke method if required:
if (this.InvokeRequired)
{
this.Invoke(new SetDataSourceDelegate(setDataSource), table);
}
else
{
progressTimer.Enabled = false;
dataGridView.DataSource = table;
progressBar.Visible = false;
}
}
private void progressTimer_Tick(object sender, EventArgs e)
{
if (this.table != null)
progressBar.Value = this.table.Rows.Count;
}
当您运行它时,您的应用程序将在加载期间保持响应,并且您会看到 ProgressBar 发生变化以反映加载的行数。只有在最后(当您在 DataGridView 上设置 DataSource 时)应用程序才会“挂起”,但我认为没有办法避免这种情况。您只能从主线程执行此操作,因此 UI 变得无响应是不可避免的。但在我的测试中,DataGridView 可以在大约一秒钟内轻松处理 300K+ 行,所以这应该不是什么大问题。