You need to enable JavaScript to run this app. C#多线程向DataGridView添加数据仍UI冻结该如何解决?
优惠活动
大模型
产品
解决方案
定价
更多

C#多线程向DataGridView添加数据仍UI冻结该如何解决?

优化方案

冻结根因

当前代码UI冻结的核心原因是高频调用Invoke抢占UI线程资源:每添加一列、每添加一行数据都会调度到UI线程执行,当数据量较大时,UI线程会被持续占用处理更新请求,无法响应用户其他操作,呈现冻结状态。同时手动逐行逐列添加控件的操作本身执行效率极低,进一步放大了卡顿问题。

优化措施

  • 取消逐行逐列手动添加行列的操作,直接将处理完成的DataTable通过DataSource属性批量绑定到DataGridView,可减少99%的UI操作量
  • 降低进度更新频率,无需每一行/每一列都更新进度,改为按百分比(如每完成10%更新一次)或者每处理固定数量数据更新一次,大幅减少Invoke调用次数
  • 绑定数据前调用SuspendLayout暂停DataGridView的布局逻辑,绑定完成后再调用ResumeLayout恢复布局,减少重复渲染开销
  • 可开启DataGridView的双缓冲特性,进一步优化渲染流畅度
  • 优先使用async/await异步方案替代手动创建Thread,无需手动处理Invoke逻辑,代码更易维护

优化后代码示例

AggregateFunction fun = (AggregateFunction)Enum.Parse(typeof(AggregateFunction), cmbAggregateFunc.Text);
// 优先使用Task.Run代替手动创建Thread
_ = Task.Run(() => prepareGrid(RowField, DataField, fun, ColumnFields));

private void prepareGrid(string RowField, string DataField, AggregateFunction aggregateFun, List<string> ColumnFields)
{
    Invoke(new MethodInvoker(delegate
    {
        var mainForm = this.MdiParent as frmMain;
        mainForm.progressBarTop.Style = ProgressBarStyle.Blocks;
        mainForm.progressBarTop.Maximum = 100;
        mainForm.progressBarTop.Value = 20;
        mainForm.progressBarTop.Visible = true;
        mainForm.toolStripLabelTop.Text = "正在获取数据……";
        dgvGrid.Visible = false;
    }));

    // 数据透视计算完全在后台线程执行,不涉及UI操作
    Pivot pvt = new Pivot(dataTable);
    dtPivot = pvt.PivotData(
        RowField,
        DataField,
        aggregateFun,
        ColumnFields.ToArray<string>());

    Invoke(new MethodInvoker(delegate
    {
        var mainForm = this.MdiParent as frmMain;
        mainForm.progressBarTop.Value = 80;
        mainForm.toolStripLabelTop.Text = "数据透视完成……";
    }));

    if (dtPivot == null)
    {
        Invoke(new MethodInvoker(delegate
        {
            var mainForm = this.MdiParent as frmMain;
            mainForm.btn_Close.Enabled = true;
            mainForm.progressBarTop.Visible = false;
            mainForm.toolStripLabelTop.Text = "";
            mainForm.btn_showReport.Enabled = true;
            MessageBox.Show("抱歉,未找到匹配数据。", Util.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            this.Close();
        }));
        return;
    }
    else
    {
        Invoke(new MethodInvoker(delegate
        {
            var mainForm = this.MdiParent as frmMain;
            mainForm.btn_Export.Enabled = true;
            mainForm.btn_Close.Enabled = false;
            mainForm.toolStripLabelTop.Text = "正在绑定数据……";
            mainForm.progressBarTop.Value = 90;

            // 批量绑定数据,替代原有循环逐行列添加逻辑
            dgvGrid.SuspendLayout();
            dgvGrid.DataSource = dtPivot;
            // 可批量设置列属性
            foreach (DataGridViewColumn col in dgvGrid.Columns)
            {
                col.ReadOnly = true;
            }
            dgvGrid.ResumeLayout();
            dgvGrid.Visible = true;

            // 重置UI状态
            mainForm.btn_Close.Enabled = true;
            mainForm.progressBarTop.Visible = false;
            mainForm.toolStripLabelTop.Text = "";
        }));
    }
}

大数据量适配方案

如果处理的数据量超过10万行,可开启DataGridView的虚拟模式,仅渲染当前可视区域的行数据,不会一次性加载所有数据到控件中,可大幅提升操作流畅度。

内容的提问来源于stack exchange,提问作者Amit Khandelwal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 05:15:03