2013-07-25 43 views
1

我在写一个WinForm应用程序时填充我的组合框有问题。我用来填充这些组合框的数据是从数据库中提取的。问题是有很多数据需要绑定到comboBoxes上,所以这个过程需要很长时间才能锁定整个应用程序(绑定数据的整个过程需要9秒钟的时间,而从数据库中提取数据只需要400毫秒)。我试图通过拆分创建控件(主线程)和填充comboBoxes(后台工作者)的过程来加快速度,但自然我得到了交叉线程错误。 这是代码的一部分,我用:设置来自backgroundWorker C#中的ComboBox DataSource

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

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

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

谢谢

+1

您需要使用'Control.BeginInvoke'或'Control.Invoke',它可以有效地将工作重定向到主线程。在这种情况下,它直接在主线程中调用'Populate'。 –

+2

您可以将加载移动到线程,但不是实际的数据绑定。从'backgroundWorker.Completed()'调用填充,而不是'.DoWork()' –

+0

@AlexFarber填充,你可以显示这样做的代码。另外,如果我将Populate方法重定向到主线程(我在ChildForm.Load方法中调用该方法时解决方案的工作正常,但速度很慢),是否会失败加速数据绑定过程的目的? – NDraskovic

回答

-1

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

无论如何。

0

我不是一个完整的瓶子上调用,但试试这个:

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

我相信这将发现线程负责对于ComboBox,这将是在同一个线程其他组合的,然后运行。

我确定有人会用更好的方式来调用,也许在表单级调用?

+0

我试过这个,它可以工作,但是如果我从主线程调用它,它的速度就会很慢,所以它不是解决方案。 – NDraskovic

相关问题