在C#中从backgroundWorker设置ComboBox DataSource

时间:2013-07-25 08:23:22

标签: c# multithreading winforms

我在我正在编写的WinForm应用程序中填充我的comboBox有问题。我用来填充这些组合框的数据是从数据库中提取的。问题是需要将大量数据绑定到组合框,因此这个过程需要很长时间才能锁定整个应用程序(绑定数据的整个过程需要9秒以上,而从数据库中提取数据只需要400毫秒)。我试图通过分割创建控件(主线程)和填充组合框(后台工作程序)的过程来加快速度,但自然我得到了交叉线程错误。 这是我使用的代码的一部分:

private void Populate()
    {                                  
        comboBox1.BindingContext = new System.Windows.Forms.BindingContext();
        comboBox1.DataSource = MyClass.dtMyDataTable;
        comboBox1.DisplayMember = "TitleColumn";

        .//I repeat the same code for each comboBox
        .//I use the BiningContext because some of the comboBoxes have to display the 
        .//same data.            
    }

我创建了一个包含我在此表单中需要的所有DataTable的类 - 有多个表单使用数据库中的相同数据,因此我创建了一个类并创建了一个对象,该对象填充了父表单上的所有这些DataTable .Load(),然后在创建它们时将它们传递给子窗体。这样我在加载应用程序时加载数据(它甚至不需要那么长时间),所以当我从子表单中调用它时它应该可以使用了。我试图从Populate()方法调用backgroundWorker.DoWork()方法,在那里我得到了交叉线程错误。

我的问题是 - 有没有办法让这项工作,如果没有,我可以用什么作为替代解决方案。

谢谢

2 个答案:

答案 0 :(得分:0)

我在调用时不是一整瓶,但试试这个:

PopulateData()
{
    if (combobox1.InvokeRequired)
    {
        combobox1.Invoke(new EventHandler(delegate(object o, EventArgs a)
            {
                PopulateData();
            }
                ));
    }
    else
    {
        // Do your updates here...
    }
}

我相信这会找到负责combobox1的线程,它将与其他组合的线程相同,然后运行。

我确定其他人会以更好的方式在表单级别调用?

答案 1 :(得分:-1)

我找到了一个很好的选择,它加速了9秒到1.5秒。解决方案是将comboBox.DisplayMember放在'comboBox.DataSource'行之前,因为当您更改DisplayMember(或ValueMember)时,数据源会重新填充自身。因此,如果comboBox.DisplayMember位于'comboBox.DataSource'行之后,数据源会自行填充2次(我认为绑定数据源时默认启用ClearBeforeFill,这就是绑定数据中没有重复的原因) )。

非常感谢。