2010-08-14 95 views
0

我想解决一个跨线程异常,无效对象异常。下面是详细信息:我有两个后台工作线程(将有更多,但我还没有编码他们,我只是编码引擎,他们都在这个时候运行。这是一个C#,Windows窗体app。每隔一段时间,BGW都会调用UpdateUI,它会对UI进行大量更新,相同的UpdateUI用于所有线程,因此它是锁定的,性能下降非常小,无关紧要很显然,我现在正在用一个BGW来改变用户界面,也就是不同的线程,所以我会得到一个交叉线程异常,所以我需要Invoke()或BeginInvoke(),但是每当我这样做时,都会以某种方式,所有这些耗时的过程都会合并到同一个线程中,并且按顺序执行,而不是同时执行。这是因为我的代码是错误的,不是因为其他原因,我真的不知道使用Invoke()和BeginInvoke(),所以这是从类似的线程复制代码,而不是我自己的,但它仍然无法正常工作,只是看它,它看起来很奇怪,而不是我会做的。跨线程异常无效对象异常

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

非常感谢你提前!

理查德

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

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

回答

2

为了确保您的UpdateUI方法是在GUI线程上执行,使用以下命令:

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

更换this与参考您的形式,如果合适的。

+0

这个工程!我不知道如何谢谢你!对不起,我不能对此投票!再次感谢! Richard – niemiro 2010-08-14 15:50:34

1

你调用调用或BeginInvoke应该是存在于目标线程控制。所以你应该使用Control.InvokeControl.BeginInvoke

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

+0

这也有助于解决问题!非常感谢! – niemiro 2010-08-14 15:52:27