2013-03-15 80 views
2

我已經創建了一個線程,其中我只是從窗體的左側移動一個單選按鈕。 這是運行,但我的應用程序被阻止,我無法移動表格,沒有任何東西(我認爲這是創建線程,同時做多件事的原因) 這是我的代碼,我希望你能理解我問了什麼。在此先感謝C#中的線程導致無限循環並阻止我的應用程序

private void moveRight() 
    { 
     radioButton1.Left++; 
    } 
    private void moveLeft() 
    { 
     radioButton1.Left--; 
    } 
    public void run() 
    { 
     while (true) 
     { 
      while (radioButton1.Left != this.ClientSize.Width - 10) 
      { 
       if (InvokeRequired) 
       { 
        Invoke(new MethodInvoker(moveRight)); 
       } 
       else 
       { 
        moveRight(); 
       } 
      } 
      while (radioButton1.Left != 10) 
      { 
       if (InvokeRequired) 
       { 
        Invoke(new MethodInvoker(moveLeft)); 
       } 
       else 
       { 
        moveLeft(); 
       } 
      } 
     } 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     t = new Thread(new ThreadStart(run)); 
     t.Start(); 
    } 
+0

謝謝你的回答,我用戶線程之前,但沒有與調用,所以我想如果我在一個線程中使用調用它將在線程中執行我調用 – patentul 2013-03-15 19:45:06

回答

7

當你調用Invoke在你告訴它運行在UI線程所提供的代碼控制。

鑑於此,您的代碼正在啓動一個新線程,然後在該線程中告訴UI線程運行一堆永久運行的代碼。

現在你明白了爲什麼UI線程被阻塞,我希望?

您需要在後臺線程中使用主while循環(即不在Invoke調用中),並將Invoke調用專門限制爲更新UI的小塊代碼。

+0

我建議也改變退出條件, != = <= – jac 2013-03-15 19:42:25

+0

我不知道你說了什麼,但我怎麼能讓這段代碼在我創建的線程中運行,同時仍然使用Invoke,我需要用戶調用,因爲否則我得到一個非法的crossThreadException,因爲單選按鈕是在UI中創建的線。 – patentul 2013-03-15 19:47:22

+0

@ user2175339這就是*我正在解釋如何在我的答案中做的。看最後一句話。你需要使用'Invoke',但你需要改變你放置的位置。您不需要將所有代碼放入「Invoke」調用中,而只需調用較小的UI更新,而將大部分工作留在「Invoke」調用之外。 – Servy 2013-03-15 19:49:03

0

嗯,有你的方法有幾個問題:

  1. 你在線程代碼永遠不會結束..你有一個無限循環
  2. 即使你正在創建一個線程,你還在運行在UI線程上的所有東西(使用Invoke)

這2個組合意味着你基本上無限地阻塞了UI線程。

從本質上講,這一點:

while (true) 
{ 
    while (radioButton1.Left != this.ClientSize.Width - 10) 
    { 
     moveRight(); 
    } 
    while (radioButton1.Left != 10) 
    { 
     moveLeft(); 
    } 
} 

永遠不會結束。並且由於它在UI線程上被調用,UI將被無限期地阻止,而只是更新控件的左側座標,而沒有任何實際呈現。

+0

謝謝你的回答,我用戶線程之前,但沒有與調用,所以我想如果我在一個線程中使用調用它將執行在線程我調用它在 – patentul 2013-03-15 19:44:43