2017-05-20 35 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并实现你的目标。