You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用OracleDataAccess.Fill填充DataTable更新DataGridView耗时过长优化咨询

优化方案

一、DataGridView渲染层面优化(50行就卡顿90%是该层面问题)

  • 当前SetDataGridView逻辑存在严重冗余:每次刷新都清空所有列、重新创建列结构再绑定数据源,而列配置是固定的,完全不需要每次重建,仅需第一次初始化时创建列,后续刷新仅更新数据源即可。
  • 绑定数据前开启渲染暂停和双缓冲,避免绑定过程中频繁重绘:
    // 绑定前暂停界面布局计算
    dgv.SuspendLayout();
    // 开启双缓冲(解决原生DataGridView渲染闪烁、卡顿问题)
    typeof(DataGridView).InvokeMember("DoubleBuffered", 
        BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty, 
        null, dgv, new object[] { true });
    
    绑定完成后恢复布局:
    dgv.ResumeLayout();
    
  • 拆分列初始化逻辑:单独封装InitDataGridViewColumns方法,仅在窗体加载或列配置变更时调用一次,后续刷新直接给DataSource赋值即可,禁止每次都执行列清空、重建逻辑。

二、数据查询逻辑优化

  • 当前Oracle相关非托管资源未手动释放,虽然有关连接的逻辑,但OracleCommand、OracleDataAdapter等对象资源泄漏会逐步拖慢查询速度,改为用using包裹所有实现IDisposable接口的对象,优化后的GetWorkList示例:
    public DataTable GetWorkList(int ordenamiento)
    {
        DataTable dtTemp = new DataTable();            
        using (OracleConnection oraConn = new OracleConnection(this.mesParameters.DBConnectionString))
        using (OracleCommand oraComm = new OracleCommand())
        using (OracleDataAdapter oraDA = new OracleDataAdapter())
        {
            try
            {
                oraComm.Connection = oraConn;
                oraComm.BindByName = true;
                oraComm.CommandType = CommandType.StoredProcedure;                                
                oraComm.CommandText = "PG_SL_IPR_WORKLIST_RF3";
    
                OracleParameter oraParam = new OracleParameter("PR_ORDER", OracleDbType.Int32, ordenamiento, ParameterDirection.Input);
                oraComm.Parameters.Add(oraParam);
    
                OracleParameter oraParamReturn = new OracleParameter("RETURN", OracleDbType.RefCursor, ParameterDirection.ReturnValue);
                oraComm.Parameters.Add(oraParamReturn);
                
                oraConn.Open();
                oraDA.SelectCommand = oraComm;
                oraDA.Fill(dtTemp);
            }
            catch (Exception ex)
            {
                this.mesMessages.OKButtonMessage("GetWorkList\r\n" + ex.Message, "MES", System.Windows.Forms.MessageBoxIcon.Error);
            }
        }
        return dtTemp;
    }
    
  • 可加时间戳日志分别统计「数据库查询耗时(oraDA.Fill前后)」和「界面绑定耗时(DataSource赋值前后)」,精准定位卡点。

三、业务场景适配优化

你的业务是每消费一条首位数据就刷新表格,完全不需要每次全量拉取数据再全量重绑:

  • 方案1:消费完首位数据后,直接删除DataGridView绑定的DataTable的第一行,界面会自动同步变更,仅当本地数据为空时再重新查询全量数据,可省掉99%的查询和重绘开销。
  • 方案2:如果必须和后端同步避免脏数据,可给存储过程加分页参数,每次仅拉取最新的前N条(比如前100条),不需要返回全量数据,进一步降低数据传输和绑定开销。

内容的提问来源于stack exchange,提问作者Gustavo Morilla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:06:04