在您的代码中,这一行将占用大部分处理时间:
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+ 行,所以这应该不是什么大问题。