2010-04-05 71 views
2

我想將MainForm中的線程從2個變量傳遞到另一個窗體,但是這樣做時會發生錯誤。使用C將線程變量從線程傳遞到另一個窗體#

private void TrackingThread() 
    { 
     float targetX = 0; 
     float targetY = 0; 

     while (true) 
     { 
      camera1Acquired.WaitOne(); 
      camera2Acquired.WaitOne(); 

      lock (this) 
      { 
       // stop the thread if it was signaled 
       if ((x1 == -1) && (y1 == -1) && (x2 == -1) && (y2 == -1)) 
       { 
        break; 
       } 

       // get middle point 
       targetX = (x1 + x2)/2; 
       targetY = (y1 + y2)/2; 
      } 

      if (directionForm != null) 
      { 
       directionForm.RunMotors(targetX, targetY); 
      } 
     } 
    } 

在形式directionForm中,我只是顯示變量targetX和targetY。 的directionForm.RunMotors()的代碼如下:

public void RunMotors(float x, float y) 
    { 
     label1.Text = "X-ordinate " + x.ToString(); 
     label2.Text = "Y-ordinate " + y.ToString(); 
    } 

當我試圖顯示兩個變量中的錯誤發生: 「InvalidOperationException異常是未處理 跨線程操作無效:控制LABEL1訪問從一個線以外的線創建線「

我該怎麼辦?

在此先感謝

+0

@kirstom:請標記您的問題是否已被回答。 – 2010-04-08 08:08:21

回答

5

整個GUI是線程安全的,你看到的錯誤是故意檢查。您必須將該方法傳遞給messagepump以使其在主線程上執行。使用類似於:

if (directionForm != null)    
{ 
    var a = new Action<float, float>(RunMotors); 
    directionForm.Invoke(a, targetX, targetY); 
} 
0

您必須從UI線程上載您的UI。在UI線程中調用一個方法。 這與Henk Holterman寫的基本相同。 UpdateUIDelegate必須具有與RunMotors方法相同的簽名。

void UpdateUI() { 
    if (this.yourControl.InvokeRequired) { 
     object[] ob = new object[] { targetX, targetY }; 
     UpdateUIDelegate updDel = new UpdateUIDelegate(RunMotors); 
     this.yourControl.Invoke(updDel, ob); 
    } 
    else { 
     this.RunMotors(targetX, targetY); 
    } 
} 

void RunMotors(targetX, targetY) 
{ 
    // action 
} 
+1

由於給出的調用總是來自另一個線程,所以您可以跳過'if(InvokeRequired)'邏輯。 – 2010-04-05 09:41:42

0

Simple Solution to Illegal Cross-thread Calls

同時檢查Control.CheckForIllegalCrossThreadCalls屬性。

當控件的創建線程以外的線程嘗試訪問某個控件的方法或屬性時,通常會導致不可預知的結果。常見的無效線程活動是訪問控件Handle屬性的錯誤線程上的調用。將CheckForIllegalCrossThreadCalls設置爲true,以便在調試時更輕鬆地找到並診斷此線程活動。請注意,在調試器外部啓動應用程序時,非法跨線程調用將始終引發異常。

相關問題