2011-07-02 30 views
1

我需要在我的应用程序中使用线程,但我不知道如何执行跨线程操作。C#.NET中的线程和交叉线程,如何从另一个线程中更改ComboBox数据?

我希望能够更改窗体对象的文本(在这种情况下,组合框),从另一个线程,我得到的错误:

Cross-thread operation not valid: Control 'titlescomboBox' accessed from a thread other than the thread it was created on. 

我真的不知道如何使用调用和开始调用函数,所以即时通讯真的寻找一个死的简单的例子和​​解释,所以我可以了解这一点。

另外,任何新手教程都会很棒,我发现了一些,但它们都非常不同,我不明白我需要做什么来执行跨线程操作。

下面是代码:

// Main Thread. On click of the refresh button 
    private void refreshButton_Click(object sender, EventArgs e) 
    { 
     titlescomboBox.Items.Clear(); 
     Thread t1 = new Thread(updateCombo); 
     t1.Start(); 
    } 

    // This function updates the combo box with the rssData 
    private void updateCombo() 
    { 
     rssData = getRssData(channelTextBox.Text);  // Getting the Data 
     for (int i = 0; i < rssData.GetLength(0); i++) // Output it 
     { 

      if (rssData[i, 0] != null) 
      { 

       // Cross-thread operation not valid: Control 'titlescomboBox' 
       // accessed from a thread other than the thread it was created on. 

       titlescomboBox.Items.Add(rssData[i, 0]); // Here I get an Error 

      } 
      titlescomboBox.SelectedIndex = 0; 
     } 
    } 

回答

8

我用下面的辅助类。

问题是控件只能从它们被创建的线程(本例中的主应用程序线程)访问。

HTH

+0

这正是我所需要的,这有助于我理解这个概念好一点! – Anil

+0

+1,用于扩展方法。我也在我的回答中推荐它。 –

+0

就像一个说明,对于ToolStripStatusLabel&ToolStripProgressBar等StatusStrip控件,应该在StatusStrip上调用包含ToolStrip控件的调用。 – jnoreiga

0

看看这个What is the best way to update form controls from a worker thread? - 它应该解决您的问题。在调用之前

public static class ControlExtensions 
{ 
    public static void Invoke(this Control control, Action action) 
    { 
     if (control.InvokeRequired) 
     { 
      control.Invoke(new MethodInvoker(action), null); 
     } 
     else 
     { 
      action.Invoke(); 
     } 
    } 
} 

现在你可以调用像MyCombo.Invoke(() => { MyCombo.Items.Add(something); }) ---或任何其它控制(如表格),因为他们都在主线程创建:

1

此异常的,因为你扔尝试访问到被另一个线程创建一个控制成员。在使用控件时,应该只从控件创建的线程访问控件成员。

控件类可以帮助您了解天气控件在创建线程上是否为否,以及是否提供InvokeRequeired属性。所以如果'control.InvokeRequeired'返回true,表明你在不同的线程。帮助你。控制支持InvokeBeginInvoke将处理方法执行到控制主线程的方法。所以:

如果您使用3.5及以上,我建议您使用Eben Roux在他的答案中显示的扩展方法。

为2.0:

// This function updates the combo box with the rssData 
private void updateCombo() 
{ 
    MethodInvoker method = new MethodInvoker(delegate() 
    { 
    rssData = getRssData(channelTextBox.Text);  // Getting the Data 
    for (int i = 0; i < rssData.GetLength(0); i++) // Output it 
    { 

     if (rssData[i, 0] != null) 
     { 

      // Cross-thread operation not valid: Control 'titlescomboBox' 
      // accessed from a thread other than the thread it was created on. 

      titlescomboBox.Items.Add(rssData[i, 0]); // Here I get an Error 

     } 
     titlescomboBox.SelectedIndex = 0; 
    } 
    }); 

    if (titlescomboBox.InvokeRequired)//if true then we are not on the control thread 
    { 
     titlescomboBox.Invoke(method);//use invoke to handle execution of this delegate in main thread 
    } 
    else 
    { 
     method();//execute the operation directly because we are on the control thread. 
    } 
} 

,如果您使用C#2.0这个

相关问题