2013-03-22 26 views
1

我是C#的初學者。當我使用win.forms時,線程出現問題。我的應用程序凍結。這個代碼有什麼問題?我正在使用msdn的微軟示例。 這裏是我的代碼:C#中的多線程與Win.Forms控件

delegate void SetTextCallback(object text); 

    private void WriteString(object text) 
    { 
     // InvokeRequired required compares the thread ID of the 
     // calling thread to the thread ID of the creating thread. 
     // If these threads are different, it returns true. 
     if (this.textBox1.InvokeRequired) 
     { 
      SetTextCallback d = new SetTextCallback(WriteString); 
      this.Invoke(d, new object[] { text }); 
     } 
     else 
     { 
      for (int i = 0; i <= 1000; i++) 
      { 
       this.textBox1.Text = text.ToString(); 
      } 
     } 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 

     Thread th_1 = new Thread(WriteString); 
     Thread th_2 = new Thread(WriteString); 
     Thread th_3 = new Thread(WriteString); 
     Thread th_4 = new Thread(WriteString); 

     th_1.Priority = ThreadPriority.Highest; // самый высокий 
     th_2.Priority = ThreadPriority.BelowNormal; // выше среднего 
     th_3.Priority = ThreadPriority.Normal; // средний 
     th_4.Priority = ThreadPriority.Lowest; // низкий 

     th_1.Start("1"); 
     th_2.Start("2"); 
     th_3.Start("3"); 
     th_4.Start("4"); 

     th_1.Join(); 
     th_2.Join(); 
     th_3.Join(); 
     th_4.Join(); 
    } 
+0

也不例外,我的表單剛剛凍結 – 2013-03-22 19:42:33

+0

您是否嘗試調試應用程序以查看它正在被掛起的位置? – 2013-03-22 19:42:53

+0

嗯,很高興知道!它什麼時候凍結? – 2013-03-22 19:42:55

回答

4

有一個僵局 - UI線程在等待線程與Thread.Join()完成而工作線程試圖使用阻塞Control.Invoke()發送消息給UI。在通過的BeginInvoke(線程代碼)更換調用會使僵局消失

if (this.textBox1.InvokeRequired) 
    { 
     SetTextCallback d = new SetTextCallback(WriteString); 
     // BeginInvoke posts message to UI thread asyncronously 
     this.BeginInvoke(d, new object[] { text }); 
    } 
    else 
    { 
     this.textBox1.Text = text.ToString(); 
    } 
+0

它的工作,但不是我的預期,它工作正常,當我添加System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;在MyApp_Load中爲 。但我讀過,不推薦。 – 2013-03-22 19:50:23

+0

嘗試添加System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false並在WriteString中刪除全部並添加textBox1.Text = text.ToString();這是我期望的結果,但我讀到它不推薦設置CheckForIllegalCrossThreadCalls = false – 2013-03-22 19:55:03

+0

你在期待什麼? – alexm 2013-03-22 19:55:59

0

凍結,因爲加入的呼叫。 Thread.Join()使當前線程在另一個完成後等待。

+0

爲什麼它不凍結,如果我添加System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;在MyApp_Load中? – 2013-03-22 19:51:59

+0

@goodspeed - 當您禁用檢查時,您會消除死鎖,因爲InvokeRequired始終返回false。 – alexm 2013-03-22 19:59:59

+0

正是什麼alexm說。您可以刪除所有.Join()調用,因爲代碼中沒有任何邏輯需要在所有線程執行其他操作之後等待。 – 2013-03-22 20:02:57