2017-05-20 38 views
-1

我想用更少的時間使用多線程來完成我的任務。但是當我運行我的線程時,它一個接一個地執行不能同時工作。如果我使用Thread.Sleep(),我的接口將被掛起,直到所有線程進程完成。這是我的代碼。多線程不能同時在C#窗體中工作

private void Form2_Load(object sender, EventArgs e) 
{ 
      dataGridView.Columns.Add("Google", "Google"); // 
      dataGridView.Columns.Add("Google1", "Google1"); 
      dataGridView.Rows.Add("google.com", ""); 
      dataGridView.Rows.Add("amazon.com", ""); 
      dataGridView.Rows.Add("flipkart.com", ""); 
      dataGridView.Rows.Add("snapdeal.com", ""); 
      dataGridView.Rows.Add("gmail.com", ""); 

      dataGridView1.Columns.Add("Google", "Google"); 
      dataGridView1.Columns.Add("Google1", "Google1"); 
      dataGridView1.Rows.Add("google.com", ""); 
      dataGridView1.Rows.Add("amazon.com", ""); 
      dataGridView1.Rows.Add("flipkart.com", ""); 
      dataGridView1.Rows.Add("snapdeal.com", ""); 
      dataGridView1.Rows.Add("gmail.com", "" 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
      Thread x = new Thread(new ThreadStart(thread1)); 
      x.Start(); 
      Thread x1 = new Thread(new ThreadStart(thread2)); 
      x1.Start(); 
} 

public void thread1() 
     { 
      Invoke(new Action(() => 
      { 

       foreach (DataGridViewRow x in lstview.Rows) 
       { 
        if (x.Cells["Google"].Value == null) 
        { 
         return; 
        } 
        if (x.Cells["Google1"].Value == "") 
        { 
         webBrowser1.ScriptErrorsSuppressed = true; 
         x.Cells["Google1"].Value = "Thread1"; 
         webBrowser1.Navigate(x.Cells["Google"].Value.ToString()); 


         while (webBrowser1.ReadyState != WebBrowserReadyState.Complete) 
         { 
          Application.DoEvents(); 
         } 

        } 
        // Task.WaitAll(); 
       } 
      })); 
} 

     public void thread2() 
     { 
      Invoke(new Action(() => 
      { 

       foreach (DataGridViewRow x in dataGridView1.Rows) 
       { 
        if (x.Cells["Google"].Value == null) 
        { 
         return; 
        } 
        if (x.Cells["Google1"].Value == "") 
        { 
         webBrowser2.ScriptErrorsSuppressed = true; 
         x.Cells["Google1"].Value = "thread2"; 
         webBrowser2.Navigate(x.Cells["Google"].Value.ToString()); 


         while (webBrowser2.ReadyState != WebBrowserReadyState.Complete) 
         { 
          Application.DoEvents(); 
         } 

        } 

       } 
      })); 
     } 

回答

0

UI元素(如您的DataGrid)只能由UI線程訪問。 WinForms和WPF/Silverlight不允許從多個線程訪問控件。

在你的情況下,你嘗試調用主線程中的代碼,這就是爲什麼它同步工作。

Sory,但沒有辦法做異步處理你的方法。因爲你所有試圖訪問UI元素的嘗試都會返回一個異常。

1

您正在創建調用Invoke方法的新線程。

看那docs此方法:

在擁有此控件的基礎 窗口句柄的線程上的委託。

所以這代表將在UI線程反正被執行還是因爲Form控制您使用屬於UI線程。

如果您刪除對Invoke的調用 - 將拋出異常,因爲您無法從非「UI」線程訪問UI元素。

如果你想加快速度,瞭解async/await或至少約BackgroundWorker

0

我相信,你的代碼的問題是訪問線程中的UI元素。線程適用於您正在執行與UI無關的特定任務的情況,可能就像調用服務來獲取數據並稍後將其綁定到UI元素一樣。當Thread中的代碼訪問UI元素時,它將最終成爲順序的,因爲UI元素只能在創建它們的線程上訪問,在這種情況下,它將成爲UI線程。

實際上,您的案例中的兩個線程都在訪問UI元素,因此會產生順序而非平行的印象。

基本上,你將不得不重構你的代碼,使它獨立於UI並實現你的目標。