C#.NET中的线程和交叉线程,如何从另一个线程更改ComboBox数据?

我需要在我的应用程序中使用线程,但我不知道如何执行交叉线程操作。

我希望能够从另一个线程更改表单对象的文本(在本例中为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; } } 

我使用以下帮助器类:

 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); }) —或任何其他控件(例如表单),因为它们都是在main上创建的线。

问题是控件只能从它们创建的线程(在这种情况下是主应用程序线程)中访问。

HTH

抛出此exception是因为您尝试访问在另一个线程上创建的控件成员。 使用控件时,只应从控件创建的线程访问控件成员。

控件类可以通过提供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这个

看一下从工作线程更新表单控件的最佳方法是什么? – 它应该解决您的问题。