我使用C#从应用程序中获取Windows 在这种形式中,我有一个按钮,它从MSSQL中的几个表中检索数据并将其显示在DataGridView中。我使用了一个后台工作程序来获取视图,我有一个进度条,我设置为marquee以向用户显示正在发生的事情,但即使我在DoWork方法中有数据检索代码,ProgressBar也没有响应,这是一些代码
The button calls the fillData() method and that method is as follows
public void fillData()
{
if (ConnectionString == "")
{
MessageBox.Show("You must connect to the server first", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
toolStripProgressBar1.Visible = true;
toolStripProgressBar1.Style = ProgressBarStyle.Marquee;
toolStripProgressBar1.MarqueeAnimationSpeed = 50;
// ....此处还有一些代码......
System.ComponentModel.BackgroundWorker backgroundworker1 = new System.ComponentModel.BackgroundWorker();
backgroundworker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
backgroundworker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundworker1_RunWorkerCompleted);
backgroundworker1.RunWorkerAsync();
}
然后我有DoWork方法
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Data.Tables.Clear();
Data.Locale = System.Globalization.CultureInfo.InvariantCulture;
System.Data.SqlClient.SqlDataAdapter masterDA = new SqlDataAdapter(sqlString, conn);
masterDA.Fill(Data, "ORDERS");
}
和RunWorkerCompleted
private void backgroundworker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
toolStripProgressBar1.MarqueeAnimationSpeed = 0;
ordersDGV.DataSource = Data.Tables[0];
recordnoTSSL.Text = ordersDGV.Rows.Count.ToString();
}
但是一旦调用后台工作者,UI就会没有响应,我认为这种技术可以让我显示进度条并保持UI响应, 我做错了什么?
答案 0 :(得分:0)
你有几个选择来解决这个问题。
1:从sql获取数据表异步不需要后台工作程序。使用SqlCommand BeginExecuteReader,您可以获得异步数据,请参阅http://msdn.microsoft.com/en-us/library/7szdt0kc.aspx
2:你永远不应该在DoWork方法中进行跨线程调用。在DoWork中创建数据集并将其设置为结果。在RunWorkerCompleted中,您可以将数据集或数据表指定为数据源:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var dataSet = new DataSet();
dataSet.Locale = System.Globalization.CultureInfo.InvariantCulture;
System.Data.SqlClient.SqlDataAdapter masterDA = new SqlDataAdapter(sqlString, conn);
masterDA.Fill(dataSet, "ORDERS");
e.Result = dataSet;
}
private void backgroundworker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if ( e.Error != null )
{
// handle exception
}
var dataSet = e.Result;
ordersDGV.DataSource = dataSet.Tables[0];
}