即使使用backgroundworker,Windows窗体UI也无法响应

时间:2014-11-07 15:15:16

标签: datagridview progress-bar backgroundworker

我使用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响应, 我做错了什么?

1 个答案:

答案 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];
}