2012-08-28 162 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