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表示你在不同的线程上。 帮助你 控制支持Invoke
和BeginInvoke
方法,它们将处理控制主线程的方法执行。 所以:
如果您使用的是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这个
看一下从工作线程更新表单控件的最佳方法是什么? – 它应该解决您的问题。