2011-03-09 80 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。