C# 用线程c填充datagridview#
我试图从sql查询填充datagridview,但这需要很长时间,我试图做的是显示一个.gif“加载”,同时填充网格,我使用线程,但.gif冻结,如果我使用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)
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
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
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线程上运行。除了解释之外,如果您可以显示如何执行的实际代码示例/代码片段,这会有所帮助!除了解释之外,如果您能展示实际的代码示例/代码片段来说明如何操作,这会有所帮助!