2011-05-22 19 views
0

當我使用委託方法運行我的方法以便刷新UI時,UI不會刷新。我想在方法運行時停止UI凍結,我該怎麼辦?關於用戶界面C中的Winform線程#

private void SearchToolStripButton_Click(object sender, EventArgs e) 
    { 
     Thread t = new Thread(new ThreadStart(StartMethod)); 
     t.Start(); 
    } 
    private delegate void InvokeDelegate(); 
    public void StartMethod() 
    { 
     this.BeginInvoke(new InvokeDelegate(SearchData)); 
    } 

    public void SearchData() 
    { 

     if (searchKeywordTextBox.Text == "") 
     { 
      MessageBox.Show("Please type the keyword!"); 
     } 
     else 
     { 
      if (searchDateTimePicker.Checked == true) 
      { 
       switch (selectRangeComboBox.Text) 
       { 
        case "Day": showDataToresultDataGridViewOnDay(searchKeywordTextBox.Text); 
         break; 
        case "Month": showDataToresultDataGridViewInMonth(searchKeywordTextBox.Text); 
         break; 
        case "Year": showDataToresultDataGridViewInYear(searchKeywordTextBox.Text); 
         break; 
        default: MessageBox.Show("Please select a Section"); 
         break; 
       } 
      } 
      else 
      { 
       showDataToresultDataGridView(searchKeywordTextBox.Text); 
      } 

     } 
    } 
    public void showDataToresultDataGridViewOnDay(string keyword) 
    { 
     DataGridView dayGrid = resultDataGridView; 
     ShowResultDay day = new ShowResultDay(); 
     resultDataGridView.DataSource = day.ShowGridDay(searchDateTimePicker.Value.Day, searchDateTimePicker.Value.Month, searchDateTimePicker.Value.Year, keyword); 
     resultLabel.Text = "Showing " + resultDataGridView.RowCount + " records in " + searchDateTimePicker.Value.Day + "/" + searchDateTimePicker.Value.Month + "/" + searchDateTimePicker.Value.Year; 
    } 
    public void showDataToresultDataGridViewInMonth(string keyword) 
    { 
     DataGridView monthGrid = resultDataGridView; 
     ShowResultMonth month = new ShowResultMonth(); 
     resultDataGridView.DataSource = month.ShowGridMonth(searchDateTimePicker.Value.Month, searchDateTimePicker.Value.Year, keyword); 
     resultLabel.Text = "Showing " + resultDataGridView.RowCount + " records in " + searchDateTimePicker.Value.Month + "/" + searchDateTimePicker.Value.Year; 
    } 
    public void showDataToresultDataGridViewInYear(string keyword) 
    { 
     DataGridView yearGrid = resultDataGridView; 
     ShowResultYear year = new ShowResultYear(); 
     resultDataGridView.DataSource = year.ShowGridYear(searchDateTimePicker.Value.Year, keyword); 
     resultLabel.Text = "Showing " + resultDataGridView.RowCount + " records in " + searchDateTimePicker.Value.Year; 
    } 
    public void showDataToresultDataGridView(string keyword) 
    { 
     ShowAllData all = new ShowAllData(); 
     var results = all.ShowGirdAll(keyword); 
     resultDataGridView.DataSource = results; 
     resultLabel.Text = "Showing " + resultDataGridView.RowCount + " records"; 
    } 
+0

你知道BeginInvoke是如何工作的嗎?如果StartMethod的所有功能都是在UI線程上調用回調度SearchData,那麼你是不是可以從後臺線程調用StartMethod。即使您已經創建了後臺線程,但它仍然毫無意義,因爲您仍然在UI線程中完成所有工作。無論你如何分片,如果你希望它們在不同的線程上運行,你需要將UI代碼與後臺代碼分開。 – 2011-05-22 18:55:48

回答

3

您應該看看BackgroundWorker類,它已被明確實現以使WinForms中的多線程更容易。

然後我建議另一件事:
不要從後臺線程打開消息框,但在啓動線程之前檢查屬性和字段,然後只運行non-ui線程中的搜索。背景工人使用的

例子:

// Initialization 
BackgroundWorker bw = new BackgroundWorker(); 
bw.DoWork += new DoWorkEventHandler(bw_DoWork); 
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); 

// Start elaboration 
bw.RunWorkerAsync(objectArgument); 

void bw_DoWork(object sender, DoWorkEventArgs e) 
{ 
    // do your work (we are in the background-thread) 
    // when you have finished, set your results in the e.Result property 
    // N.B. don't show anything because we are in the background-thread 
} 

void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    // here we have finished the work (we are in the UI-thread) 
    // result is set in e.Result property 
    // N.B. check e.Error property before to get e.Result because 
    //  if there's an error e.Result throws an exception 
} 
0

與天然的Win32 API或MFC,點網框架不支持多線程的UI方法對控制的*通話。因此,你不能在任何線程中創建UI控件(窗口),並調用它的方法並從另一個屬性設置屬性! (*這裏和下面 - UI方法更新(刷新)UI上下文。您可以從控件讀取數據並且不能寫入) 順便說一下,在本機環境中,這些調用也不能可靠地工作,有時會拋出管理不好的異常...... 但是託管環境不能允許方法調用會導致異常!它只是「凍結」了一次這樣的呼叫,並沒有做任何更新。順便提一下,該平臺的這個功能不僅適用於後臺線程。無論是調用BeginInvoke(來自內置線程池),還是以另一種方式創建用戶的非後臺線程,都會遇到同樣的問題。 在您的具體情況下,我看不到任何理由讓兩個或更多線程共享相同的控制權 - 這在數據安全性方面也很危險。通常,其他線程(通常是並行)用於完全不同的目的:用於任何長時間計算,數據庫,文件,網絡的I/O操作。 雖然,您當然可以在其他線程中調用某些消息框。