【问题标题】:populate datagridview with thread c#用线程c#填充datagridview
【发布时间】:2015-01-07 14:12:04
【问题描述】:

我试图从 sql 查询中填充 datagridview 但它需要很长时间,我试图做的是显示 .gif “加载”同时填充网格,我使用线程但 .gif 冻结,并且如果我使用CheckForIllegalCrossThreadCalls = false;,datagridview 不会加载滚动条的行为很奇怪。这是我的代码

delegate void CambiarProgresoDelegado(); 

按钮点击

 private void btn_busca_Click(object sender, EventArgs e)
    {
        pictureBox1.Visible = true;
       thread=  new Thread(new ThreadStart(ejecuta_sql));
        thread.Start();
    }

方法

private void ejecuta_sql()
    {

if (this.InvokeRequired)
        {         

         CambiarProgresoDelegado delegado = new CambiarProgresoDelegado(ejecuta_sql);

        object[] parametros = new object[] { };
          this.Invoke(delegado, parametros);
       }
        else
        {
            myConnection.Open();
            SqlCommand sql_command2;
            DataSet dt2 = new DataSet();

            sql_command2 = new SqlCommand("zzhoy", myConnection);
            sql_command2.CommandType = CommandType.StoredProcedure;
            sql_command2.Parameters.AddWithValue("@FechaIni", dateTimePicker1.Value.ToShortDateString());
            sql_command2.Parameters.AddWithValue("@FechaFin", dateTimePicker2.Value.ToShortDateString());
            SqlDataAdapter da2 = new SqlDataAdapter(sql_command2);
            da2.Fill(dt2, "tbl1");
            grid_detalle.DataSource = dt2.Tables[0];
            myConnection.Close();
            pictureBox1.Visible = false;


        }

.gif 文件会冻结,直到线程完成他的工作。

【问题讨论】:

    标签: c# multithreading datagridview


    【解决方案1】:

    您创建了一个线程,但随后立即使用 Invoke() 将代码切换回主 UI 线程,从而否定了首先创建线程的任何好处。

    在另一个线程上运行查询,然后 Invoke() 只是更新 UI 的部分:

        private string FechaIni;
        private string FechaFin;
    
        private void btn_busca_Click(object sender, EventArgs e)
        {
            btn_busca.Enabled = false;
            pictureBox1.Visible = true;
            FechaIni = dateTimePicker1.Value.ToShortDateString();
            FechaFin = dateTimePicker2.Value.ToShortDateString();
            thread = new Thread(new ThreadStart(ejecuta_sql));
            thread.Start();
        }
    
        private void ejecuta_sql()
        {
            myConnection.Open();
            SqlCommand sql_command2;
            DataSet dt2 = new DataSet();
    
            sql_command2 = new SqlCommand("zzhoy", myConnection);
            sql_command2.CommandType = CommandType.StoredProcedure;
            sql_command2.Parameters.AddWithValue("@FechaIni", FechaIni);
            sql_command2.Parameters.AddWithValue("@FechaFin", FechaFin);
            SqlDataAdapter da2 = new SqlDataAdapter(sql_command2);
            da2.Fill(dt2, "tbl1");
            myConnection.Close();
    
            this.Invoke((MethodInvoker)delegate { 
                grid_detalle.DataSource = dt2.Tables[0];
                pictureBox1.Visible = false;
                btn_busca.Enabled = true;
            });
        }
    

    【讨论】:

    • 谢谢!!像魅力一样工作,所以我只使用 Invoke 来更新主线程的 UI 对吗?
    • 没错。 “工作”在您创建的线程上完成,并且仅调用 UI 更新,导致它们在主 UI 线程上运行。
    【解决方案2】:

    您可以考虑改变您的方法,尤其是当您从后台线程进行大量 GUI 更新时。原因:

    • UI 更新需要时间,而且由于您必须锁定,它会减慢后台处理速度
    • 来自后台线程的更新过多会使 UI 不堪重负,并可能导致死机。
    • 您可能不想每毫秒左右更新一次 GUI

    我更喜欢轮询后台线程数据。将 GUI 计时器设置为 300 毫秒,然后检查是否有任何数据准备好更新,然后使用适当的锁定进行快速更新。

    这里是代码示例:

        private string text = "";
        private object lockObject = new object();
    
        private void MyThread()
        {
            while (true)
            {
                lock (lockObject)
                {
                    // That can be any code that calculates text variable,
                    // I'm using DateTime for demonstration:
                    text = DateTime.Now.ToString();
                }
            }
        }
    
        private void timer_Tick(object sender, EventArgs e)
        {
            lock(lockObject)
            {
                label.Text = text;
            }
        }
    

    请注意,虽然文本变量更新非常频繁,但 GUI 仍然保持响应。相反,如果您在每次“文本”更改时更新 GUI,您的系统将冻结。

    【讨论】:

    • 连同解释,如果您能展示实际的代码示例/sn-p 说明如何操作,将会很有帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多