2011-03-09 108 views
2

逗人,我收到錯誤消息時,波紋管我嘗試調用排序方法:跨線程操作無效

錯誤消息:跨線程操作無效:控制「lbStart_Bubble」從其他線程訪問而不是它創建的線程。

什麼在這裏做得不正確!?

Thread thBubble = new Thread(new ThreadStart(bubbleSort)); 
thBubble.Start(); 


public void bubbleSort() 
    { 
     int row = 0, column = 0; 

     start = new TimeSpan(System.DateTime.Now.Ticks); 
     lbStart_Bubble.Text = start.ToString(); 
     this.lbStart_Bubble.Refresh(); 

     for(row = 1; row <= list1.Length; row++) 
     { 
      for(column =0; column < list1.Length-1; column++) 
      { 

       Thread.Sleep(delay); 
       tbResult_Bubble.Clear(); 
       for(int i=0; i<list1.Length; i++) 
        tbResult_Bubble.AppendText(list1[i] + " "); 

       if(list1[column]>list1[column+1]) 
        swap(list1[column], list1[column+1], column, column+1); 
      } 
      display(list1); 
     } 

     end = new TimeSpan(System.DateTime.Now.Ticks); 
     lbEnd_Bubble.Text = end.ToString(); 

     lbTotal_Bubble.Text = end.Subtract(start).ToString(); 

     tbResult_Bubble.Clear(); 

     for(int i=0; i<list1.Length; i++) 
      tbResult_Bubble.AppendText(list1[i] + " "); 

    } 
+0

您應該用正在使用的語言標記問題。看起來像Java? – 2011-03-09 12:58:31

+0

經過猜測:) – 2011-03-09 13:03:22

+0

我會下次再見。 – Gogolo 2011-03-09 13:04:47

回答

7

您不能與來自不同於創建的線程的控件交談,因此擁有該控件。

因此,對於一個人來說,您不能像這樣完成標籤的使用。

相反,你可以InvokeBeginInvoke

lbStart.Invoke(new Action(() => 
{ 
    lbStart_Bubble.Text = start.ToString(); 
})); 

或:

lbStart.BeginInvoke(new Action(() => 
{ 
    lbStart_Bubble.Text = start.ToString(); 
})); 

不同之處在於,首先會等待,直到主線程(擁有該標籤的一個)已執行它之前的代碼(後臺線程)繼續執行。想想它有一個常規的方法調用,它只發生在另一個線程上。

第二個會發送郵件給擁有標籤的線程,要求它執行這段代碼,然後不要等待它。這可能會很棘手,例如如果start在主線程執行該代碼之前在後臺線程中發生了變化,那該怎麼辦?

我會使用Invoke,直到獲得更多的線程體驗,然後研究替代方法。

或者,您可以使用BackgroundWorker,它可以安全地將進度消息發送回主線程。

1

您不能通過與創建它的線程不同的線程驅動用戶界面。看看Control.Invoke並使用它從後臺線程中驅動UI。