背景工作者尝试

时间:2016-11-07 19:27:10

标签: c# winforms backgroundworker

这是该函数最初的用法:

    void fillLiguanea()
    {
        items = new List<string>();
        this.liguanea_Lane2TableAdapter.Fill(this.pharmaciesDataSet3.Liguanea_Lane2);
        try
        {

            string connectionString = "Data Source=LPMSW09000012JD\\SQLEXPRESS;Initial Catalog=Pharmacies;Integrated Security=True";
            SqlConnection con = new SqlConnection(connectionString);
            con.Open();
            string query = "SELECT * FROM dbo.Liguanea_Lane2";
            SqlCommand cmd = new SqlCommand(query, con);

            SqlDataReader dr = cmd.ExecuteReader();
            while (dr.Read())
            {
                string scode = dr.GetString(dr.GetOrdinal("code"));
                comboBox2.Items.Add(scode);

            }
        }
        catch (Exception ex)
        {

            MessageBox.Show(ex.ToString());
        }
    }

现在考虑后台工作人员的方式如下:

 private List <string> items;
    void fillLiguanea()
    {
        items = new List<string>();
        this.liguanea_Lane2TableAdapter.Fill(this.pharmaciesDataSet3.Liguanea_Lane2);
        try
        {

            string connectionString = "Data Source=LPMSW09000012JD\\SQLEXPRESS;Initial Catalog=Pharmacies;Integrated Security=True";
            SqlConnection con = new SqlConnection(connectionString);
            con.Open();
            string query = "SELECT * FROM dbo.Liguanea_Lane2";
            SqlCommand cmd = new SqlCommand(query, con);

            SqlDataReader dr = cmd.ExecuteReader();
            while (dr.Read())
            {
                string scode = dr.GetString(dr.GetOrdinal("code"));
                // comboBox2.Items.Add(scode);
                items.Add(scode);
            }
        }
        catch (Exception ex)
        {

            MessageBox.Show(ex.ToString());
        }
    }

下面是我的后台工作程序函数,它们已被编辑以填充有问题的comboBox,即comboBox2。 这是我的背景工作者:

     private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        fillLiguanea();
    }

这是我的RunWorkerCompleted:

  private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {

        if (comboBox4.SelectedIndex == 0)
        {


            foreach (var item in items)
            {
                comboBox2.Items.Add(item);
            }
        }
    }

我的问题是我哪里出错了?代码应该做的是根据combox4索引的选择从我的数据库中填充comboBox2。目前没有任何反应我哪里错了?

1 个答案:

答案 0 :(得分:1)

使用BackgroundWorker时,您可以考虑这样的模式:

  1. 处理DoWork事件并在那里调用耗时的任务 请记住,事件是在与UI线程不同的另一个线程中引发的,因此如果出于任何原因想要在事件中执行一些UI代码,则应使用Invoke创建一个线程安全调用UI元素 在DoWork中投入耗时的UI任务是没用的。因为任务应该使用Invoke在UI线程中运行,它将使UI线程再次忙碌。

  2. 您可以处理RunWorkerCompleted事件,以便在DoWork完成工作后执行某些任务。例如,在DoWork中加载数据后,您可以使用RunWorkerCompleted中加载的数据来填充ComboBox

  3. 您应该调用组件的RunWorkerAsync方法来开始处理DoWork事件 ○当使用组件实例运行异步任务时,无法使用同一组件启动另一个任务,因此为防止异常,您应检查this.backgroundWorker1.IsBusy,如果组件不忙,请调用该方法。

  4. 该组件对错误报告或更改或取消执行的进度有很好的支持。要了解有关这些功能的更多信息,请查看documentations

  5. 对于.NET 4.5及更高版本,您可以使用async/await模式执行异步任务。

  6. 示例

    我想你目前有一个LoadData方法:

    public void LoadData()
    {
        this.categoryTableAdapter.Fill(this.testDBDataSet.Category);
    }
    

    并且您希望使用LoadData加载的数据填充控件。因此,您可以像这样处理DoWorkRunWorkerCompleted

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        LoadData();
    }
    
    private void backgroundWorker1_RunWorkerCompleted(object sender, 
        RunWorkerCompletedEventArgs e)
    {
        this.comboBox1.DataSource = this.testDBDataSet.Category;
        this.comboBox1.DisplayMember = "Name";
    }
    

    此外,您应该在任务开始时调用RunWorkerAsync,例如:

    private void button1_Click(object sender, EventArgs e)
    {
        if (!this.backgroundWorker1.IsBusy)
            this.backgroundWorker1.RunWorkerAsync();
    }