Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用线程c填充datagridview#_C#_Multithreading_Datagridview - Fatal编程技术网

C# 用线程c填充datagridview#

C# 用线程c填充datagridview#,c#,multithreading,datagridview,C#,Multithreading,Datagridview,我试图从sql查询填充datagridview,但这需要很长时间,我试图做的是显示一个.gif“加载”,同时填充网格,我使用线程,但.gif冻结,如果我使用CheckForIllegalCrossThreadCalls=falsedatagridview不加载滚动条。这是我的密码 delegate void CambiarProgresoDelegado(); 按钮点击 private void btn_busca_Click(object sender, EventArgs e)

我试图从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将一直冻结,直到线程完成其任务。

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

在另一个线程上运行查询,然后仅调用更新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的部分:

    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;
        });
    }

<>你可以考虑改变你的方法,特别是当你从后台线程做很多GUI更新的时候。原因:

  • UI更新需要时间,而且会减慢后台处理,因为您必须锁定
  • 来自后台线程的太多更新将淹没UI并可能导致冻结
  • 您可能不想每隔毫秒左右更新一次GUI
我更喜欢轮询后台线程数据。将GUI定时器设置为300ms,然后检查是否有任何数据准备好更新,然后使用正确的锁定进行快速更新

下面是代码示例:

    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,您的系统将冻结。

< P>您可以考虑更改您的方法,特别是如果您正在从后台线程中进行大量GUI更新。原因:

  • UI更新需要时间,而且会减慢后台处理,因为您必须锁定
  • 来自后台线程的太多更新将淹没UI并可能导致冻结
  • 您可能不想每隔毫秒左右更新一次GUI
我更喜欢轮询后台线程数据。将GUI定时器设置为300ms,然后检查是否有任何数据准备好更新,然后使用正确的锁定进行快速更新

下面是代码示例:

    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,您的系统将冻结。

谢谢!!就像charm一样工作,所以我只使用调用来更新主线程的UI,对吗?没错。“工作”是在您创建的线程上完成的,只调用对UI的更新,导致它们在主UI线程上运行。谢谢!!就像charm一样工作,所以我只使用调用来更新主线程的UI,对吗?没错。“工作”是在您创建的线程上完成的,只调用对UI的更新,从而使它们在主UI线程上运行。除了解释之外,如果您可以显示如何执行的实际代码示例/代码片段,这会有所帮助!除了解释之外,如果您能展示实际的代码示例/代码片段来说明如何操作,这会有所帮助!