2012-08-28 113 views
1

Possible Duplicate:
Why am I getting this error:“Cross-thread operation not valid: Control lbFolders accessed from a thread other than the thread it was created on.”?
Invoke or BeginInvoke cannot be called on a control until the window handle has been created跨线程操作无效

我有线程问题。

我每隔600毫秒从COM端口获取数据,当我处于调试模式时,出现几秒钟后出现错误,但是当我处于非调试运行模式时,我在一两分钟后出错,但错误持续。

我得到的错误发生在每个线程上调用的某些函数上。

以下是错误的图片:

ERROR

代码的其他部分:

private void LoadData() 
     { 
      while (td.IsAlive) 
      { 
       eng.GetSpeedKmh(); 
       eng.GetEngineRpm(); 
       eng.GetCalculatedEngineLoadValue(); 
       eng.GetFuelLevelInput(); 
       eng.GetEngineTemp(); 
       eng.MAF(); 

       System.Threading.Thread.Sleep(600); 
      } 
     } 

我能做些什么来解决这个问题?

+4

【如何:使线程安全的调用到Windows窗体控件(http://msdn.microsoft.com/en-us/library/ms171728(V = VS。 80).aspx) –

+0

错误信息告诉你一切你可能想知道的。 –

+0

@DavidSchwartz:我想他们也想知道如何解决这个问题。 – Jon

回答

2

尝试下面的代码

public void eng_OnGetSpeedDone(OBDIIEngineEventArgs args) 
     { 
      if (this.InvokeRequired) 
      { 
       Action action =() => eng_OnGetSpeedDone(args); 
       Invoke(action); 
       return; 
      } 
      if (!args.OBDResultNoData) 
       brzina_ele.Text = arg.OBDValue.ToString(); 
      else 
       brzina_ele.Text = "0"; 

     } 
+0

你能解释我这个代码吗 –

+0

因为Winforms在STA上工作所以跨线程操作应该被主要UI线程封送到UI .... InvokeRequired是UI控件的属性,有助于检查是否调用是跨线程。要编组交叉线程调用,你可以使用Invoke或BeginInvoke方法,这将调用UI线程...调用方法期望委托作为参数和委托应该是相同的签名作为您的方法...我用动作委托与lambda表达式创建委托的实例。然后调用Invoke方法在UI线程上调用相同的方法。 –

+0

如果你想异步操作,那么你可以使用BeginInvoke而不是Invoke。 –

-1

调用。文本属性的编辑:

this.Invoke((MethodInvoker) delegate { brzina_ele.Text = "Its new value"; }); 

您还可以通过使用它的Tick事件做呼叫从Windows.Forms.Timer。这是更线程安全的,并且拥有你需要的一切。

+0

-1:你的回答是NeerajKaushik。以前的答案的一个非常有限的副本,谁提出了可重复使用的“反弹”方法。您试图添加另一个选项,但是您提出的建议并不是非常有用 - 请看问题:他使用COM端口,并且他提供的代码是异步回调“On-GetSpeed - Done”,因此可能他有一个带有阻塞读取超时的bgthread。 “OBD”也表明这一点。建议将异步变成一个UI绑定的回调(因此,将阻止用户界面的轮询)对我来说似乎不太合理.. – quetzalcoatl