C# 在C中从backgroundWorker设置ComboBox数据源#

C# 在C中从backgroundWorker设置ComboBox数据源#,c#,multithreading,winforms,C#,Multithreading,Winforms,我在编写的WinForm应用程序中填充组合框时遇到问题。我用来填充这些组合框的数据是从数据库中提取的。问题是有很多数据需要绑定到组合框,因此这个过程需要很长的时间,整个应用程序都会被锁定(绑定数据的整个过程需要9秒以上,而从数据库中提取数据的过程只需要400毫秒)。我试图通过拆分创建控件(主线程)和填充组合框(后台工作程序)的过程来加快速度,但我自然会遇到跨线程错误。 这是我使用的代码部分: private void Populate() {

我在编写的WinForm应用程序中填充组合框时遇到问题。我用来填充这些组合框的数据是从数据库中提取的。问题是有很多数据需要绑定到组合框,因此这个过程需要很长的时间,整个应用程序都会被锁定(绑定数据的整个过程需要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.            
    }
我创建了一个包含此表单中所需的所有数据表的类-有多个表单使用来自数据库的相同数据,因此我创建了一个类并创建了一个对象,用于填充父表单.Load()上的所有这些数据表,然后在创建子表单时将它们传递给子表单。通过这种方式,我在应用程序加载时加载数据(它甚至不需要那么长时间),因此当我从子窗体调用它时,它应该准备好使用。我试图从
backgroundWorker.DoWork()
方法调用
Populate()
方法,结果得到了跨线程错误

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


谢谢你

调用时我不是满满一瓶,但请尝试以下方法:

PopulateData()
{
    if (combobox1.InvokeRequired)
    {
        combobox1.Invoke(new EventHandler(delegate(object o, EventArgs a)
            {
                PopulateData();
            }
                ));
    }
    else
    {
        // Do your updates here...
    }
}
我相信这将找到负责Combox1的线程,它将是另一个Combox的相同线程,然后运行


我相信其他人会提出一种更好的方法来调用,也许是在表单级别?

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


无论如何,谢谢。

您需要使用
Control.BeginInvoke
Control.Invoke
,这将有效地将工作重定向到主线程。在此上下文中,与直接在主线程中调用
填充
相同。您可以将加载移动到线程,但不能移动到实际的数据绑定。从
backgroundWorker.Completed()
,而不是从
.DoWork()
@AlexFarber()调用populated,能否显示执行此操作的代码。另外,如果我将Populate方法重定向到主线程(我在ChildForm.Load方法中调用它时的解决方案工作正常,但速度非常慢),它不会破坏加快数据绑定过程的目的吗?您可以按照Henk Holterman的建议使用backgroundWorker.Completed()。Form.Load事件的替代方法-从Form.Load异步运行此操作,而不是直接调用,请使用BeginInvoke。在这种情况下,将显示表单,并在一段时间后填充它。没有延迟显示表单-在这种情况下,这是最好的。谢谢,我将我的解决方案与此相结合,现在它工作得很好。我尝试过这个,它工作得很好,但速度很慢,就像我从主线程调用它一样,所以它不是一个解决方案。