简体   繁体   English

在C#中从backgroundWorker设置ComboBox DataSource

[英]Setting ComboBox DataSource from backgroundWorker in C#

I have a problem with populating my comboBoxes in a WinForm application that I'm writing. 我在编写的WinForm应用程序中填充comboBoxes时遇到问题。 The data that I use to populate these comboBoxes is pulled from database. 我用来填充这些comboBox的数据是从数据库中提取的。 The problem is that there is a lot of data that needs to be binded to the comboBoxes, so this process takes a very long time during which the entire application is locked (the entire process of binding data takes over 9 seconds, while the process of pulling the data from the database takes only 400 milliseconds). 问题在于,有很多数据需要绑定到comboBoxes,因此此过程需要很长时间才能锁定整个应用程序(绑定数据的整个过程需要9秒钟以上,而从数据库中提取数据仅需400毫秒)。 I'm trying to speed things up by splitting the processes of creating the controls (main thread) and populating the comboBoxes (background worker), but naturally I get the cross thread error. 我试图通过拆分创建控件(主线程)和填充comboBoxes(后台工作程序)的过程来加快处理速度,但是自然会遇到跨线程错误。 This is the part of code that I use: 这是我使用的代码部分:

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.            
    }

I created a class that contains all DataTables that I need in this form - there are multiple forms that use the same data from the database, so I created a class and created an object that fills all of these DataTables on the parent Form.Load(), and then I pass them to the children forms when I create them. 我创建了一个包含该表单所需的所有DataTables的类-有多种使用数据库中相同数据的表单,因此我创建了一个类并创建了一个对象,该对象填充了父Form.Load( ),然后在创建它们时将它们传递给子窗体。 This way I load the data when the application loads (it doesen't even take that long), so it should be ready to use when I call it from child forms. 通过这种方式,我可以在应用程序加载时加载数据(它甚至不需要花费那么长的时间),因此当我从子窗体中调用它时应该可以使用它。 I've tried to call the Populate() method from backgroundWorker.DoWork() method, and there I get the cross thread error. 我试图从backgroundWorker.DoWork()方法调用Populate()方法,然后出现跨线程错误。

My question is - is there a way to make this work, and if not, what could I use as alternative solution. 我的问题是-有没有办法使这项工作奏效,如果没有,我可以使用什么作为替代解决方案。

Thank you 谢谢

I'm not a full bottle on invoking but try this: 我在调用时还不够用,但是请尝试以下操作:

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

I believe this will find the thread responsible for combobox1, which is going to be the same thread for the other combo's, and then run. 我相信这将找到负责combobox1的线程,该线程将与其他combobox1的线程相同,然后运行。

I'm sure someone else will chime in with a better way to invoke perhaps at the form level ? 我确定其他人会以一种更好的方式(可能在表单级别)进行调用吗?

I've found a good alternative, and it sped things up from 9 seconds to 1.5 seconds. 我找到了一个不错的选择,它将速度从9秒提高到1.5秒。 The solution is to place the comboBox.DisplayMember BEFORE the 'comboBox.DataSource' line because when you change the DisplayMember (or ValueMember) the data source repopulates itself. 解决方案是将comboBox.DisplayMember放在'comboBox.DataSource'行之前,因为更改DisplayMember(或ValueMember)时,数据源会重新填充。 So if the comboBox.DisplayMember is after the 'comboBox.DataSource' line, the data source populates itself 2 times (I think that ClearBeforeFill is enabled by default when binding data sources, that is why there are no duplicates in the binded data). 因此,如果comboBox.DisplayMember位于'comboBox.DataSource'行之后,则数据源将自身填充2次(我认为绑定数据源时默认情况下会启用ClearBeforeFill,这就是为什么绑定数据中没有重复项的原因)。

Thanks anyway. 不管怎么说,还是要谢谢你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM