我需要在我的应用程序中使用线程,但我不知道如何执行交叉线程操作。
我希望能够更改form对象(在本例中为Combo Box)的文本,从另一个线程中,我得到了错误:
Cross-thread operation not valid: Control 'titlescomboBox' accessed from a thread other than the thread it was created on.我真的不知道如何使用invoke和begin invoke函数,所以我真的在寻找一个非常简单的例子和解释,这样我就可以了解它了。
此外,任何初学者教程都会很棒,我找到了一些,但它们都是如此不同,我不知道我需要做什么来执行交叉线程操作。
代码如下:
// 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;
}
}发布于 2011-07-02 18:09:18
我使用下面的helper类:
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); }) -或任何其他控件(如表单)的内容,因为它们都是在主线程上创建的。
问题是,控件只能从创建它们的线程(在本例中是主应用程序线程)访问。
HTH
发布于 2011-07-02 18:19:59
引发此异常是因为您试图访问在另一个线程上创建的控件成员。使用控件时,应仅从在其上创建控件的线程访问控件成员。
通过提供InvokeRequeired属性,控件类可以帮助您了解控件在创建的线程上是否为no。因此,如果'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,则如下所示
发布于 2011-07-02 18:07:45
看看这个What is the best way to update form controls from a worker thread? -它应该能解决你的问题。
https://stackoverflow.com/questions/6556330
复制相似问题