交叉线程异常无效对象异常

时间:2010-08-14 13:40:01

标签: c#

我正试图解决交叉线程异常,无效对象异常。以下是详细信息:我有两个后台工作线程(还有更多,但我还没有对它们进行编码,我只是编写引擎以便它们全部运行。这是一个C#,Windows Forms应用程序。每隔一段时间,BGW就会调用UpdateUI,它会对UI进行大量的更新。同一个UpdateUI用于所有线程,因此它是Locked。性能降低很小,无关紧要显然,我现在用BGW改变UI,即一个不同的线程,所以我将得到一个Cross Thread Exception,所以我需要Invoke()或BeginInvoke(),但每当我这样做时,不知何故,所有这些耗时的进程都被合并到同一个线程上,并按顺序执行,而不是同时执行。这将是因为我的代码错了,不是因为任何其他原因。我真的不知道如何使用Invoke()和BeginInvoke(),所以这是从类似的线程复制代码,而不是我自己的,但它仍然不起作用。只是看着它,它看起来很奇怪,而不是我本来会做的。

那么,你能帮我纠正一下我的Invoke()代码吗?它删除了异常,但将它们全部合并到一个线程上,但不完全确定哪个是UI线程?另外,我的UpdateUI()非常冗长和复杂,理想情况下,我会调用整个方法(基本上整个事情都需要调用),而不是单独的每一行,如果可能的话,就像打击代码一样。我再说一遍,这不是我用于Invoke()方法,而只是改变一个“Enabled”状态,这就是为什么它看起来很奇怪。

提前非常感谢你!

理查德

MethodInvoker method = delegate
{
    label3.Enabled = true;
};

if (InvokeRequired)
{
    BeginInvoke(method);
}
else
{
    method.Invoke();
}

2 个答案:

答案 0 :(得分:2)

要确保在GUI线程上执行UpdateUI方法,请使用以下命令:

public void UpdateUI() {
    if (this.InvokeRequired) {
        this.Invoke(new MethodInvoker(UpdateUI));
    } else {
        // Changes to UI are made here.
    }
}

如果合适,请将<{1}}替换为对表单的引用。

答案 1 :(得分:1)

您对Invoke或BeginInvoke的调用应该在目标线程中存在的控件上。因此,您应该使用Control.InvokeControl.BeginInvoke

内部调用实际上向UI线程消息队列发送消息(同步),并且BeginInvoke将消息(异步)发布到消息队列,因为消息队列一次处理一个消息,您可能不需要锁定在调用Invoke / BeginInvoke。