伙计们,我知道这个问题已经问过很多次了,但我仍然找不到一个对我来说有意义的答案。
我有一个有400多个控件的表单。
我有一个后台线程,它轮询一堆设备并收集要显示在表单上的各种数据。
然后,我将一个方法称为"UpdateDisplay(string[] data)“。这个例程接受字符串数组data[]中的所有信息,并填充表单上的所有组件。我有标签,TextBoxes正在填写。面板、TableLayouts和其他控件正在显示和隐藏。
数以百计的人!
如果我必须测试每一个组件,看看我是否必须调用我的程序将变成50亿行代码!
是否有什么方法可以简单地查看整个UpdateDisplay方法是否需要在UI线程上调用,而不是它所涉及的所有400+组件?
我放置了以下代码:
if (InvokeRequired)
{
BeginInvoke(new MethodInvoker(() => UpdateDisplay(data)));
}
作为显示方法中的第一个语句,我不再获得关于从非ui线程调用ui组件的运行时异常。
接下来是update方法的其余部分,使用data[]中的信息更新数百个组件
但是现在我在System.Forms.dll得到了一堆System.InvalidOperationException?
如果我将调试异常选项设置为对所有无效操作异常进行中断,则在使用有关从非ui线程更新组件的nastygram更新UpdateDisplay方法中的组件时,会看到它们被随机抛出。
有人能帮我理解并解决这个问题吗?
我可以发布整个UpdateDisplay方法,以说明如果我必须用调用的if语句包装每个组件更新调用,那将是多么不明智。如果不夸张的话,它会在每个控件中增加三行代码,或者大约1200行额外代码!!太疯狂了!
发布于 2015-11-11 13:04:02
您没有提供足够的代码,但是如果您的方法如下所示:
void UpdateDisplay(string[] data)
{
if (InvokeRequired)
{
BeginInvoke(new MethodInvoker(() => UpdateDisplay(data)));
}
Label1.Text = data[0];
// Update more controls here
}
然后,您将运行两次UpdateDisplay
,一次是在UI线程上运行,一次是由于BeginInvoke
而运行,一次是在BeginInvoke
返回时在工作线程上运行。通常的模式是,如果使用Invoke
或BeginInvoke
调用自己,则该方法将立即返回,不再进行进一步处理:
void UpdateDisplay(string[] data)
{
if (InvokeRequired)
{
BeginInvoke(new MethodInvoker(() => UpdateDisplay(data)));
return; // Don't run any code below when BeginInvoke returns
}
Label1.Text = data[0];
// Update more controls here
}
JimmyV还提供了一个替代版本,在BeginInvoke
之后也不再做进一步的工作。
void UpdateDisplay(string[] data)
{
if (InvokeRequired)
{
BeginInvoke(new MethodInvoker(() => UpdateDisplay(data)));
}
else // Don't run any code below when BeginInvoke returns
{
Label1.Text = data[0];
// Update more controls here
}
}
发布于 2015-11-11 12:59:35
这是我如何用来自另一个线程的消息更新ListBox的示例。
private void WriteProgressMessage(string message)
{
if (this.InvokeRequired)
{
this.Invoke(new Action(() => this.WriteProgressMessage(message)));
}
else
{
this.ProgressList.Items.Add(message);
this.ProgressList.SelectedIndex = this.ProgressList.Items.Count - 1;
this.ProgressList.SelectedIndex = -1;
}
}
发布于 2015-11-11 13:07:40
一种可能是,由于您正在使用BeingInvoke
、rather than Invoke
来更新UI线程,因此可能会出现同步问题。如果没有看到更完整的代码示例,很难判断,请尝试调用Invoke
,看看是否获得了较少的错误。
https://stackoverflow.com/questions/33659617
复制相似问题