2011-07-02 27 views
1

我需要在我的應用程序中使用線程,但我不知道如何執行跨線程操作。C#.NET中的線程和交叉線程,如何從另一個線程中更改ComboBox數據?

我希望能夠更改窗體對象的文本(在這種情況下,組合框),從另一個線程,我得到的錯誤:

Cross-thread operation not valid: Control 'titlescomboBox' accessed from a thread other than the thread it was created on. 

我真的不知道如何使用調用和開始調用函數,所以即時通訊真的尋找一個死的簡單的例子和​​解釋,所以我可以瞭解這一點。

另外,任何新手教程都會很棒,我發現了一些,但它們都非常不同,我不明白我需要做什麼來執行跨線程操作。

下面是代碼:

// Main Thread. On click of the refresh button 
    private void refreshButton_Click(object sender, EventArgs e) 
    { 
     titlescomboBox.Items.Clear(); 
     Thread t1 = new Thread(updateCombo); 
     t1.Start(); 
    } 

    // This function updates the combo box with the rssData 
    private void updateCombo() 
    { 
     rssData = getRssData(channelTextBox.Text);  // Getting the Data 
     for (int i = 0; i < rssData.GetLength(0); i++) // Output it 
     { 

      if (rssData[i, 0] != null) 
      { 

       // Cross-thread operation not valid: Control 'titlescomboBox' 
       // accessed from a thread other than the thread it was created on. 

       titlescomboBox.Items.Add(rssData[i, 0]); // Here I get an Error 

      } 
      titlescomboBox.SelectedIndex = 0; 
     } 
    } 

回答

8

我用下面的輔助類。

問題是控件只能從它們被創建的線程(本例中的主應用程序線程)訪問。

HTH

+0

這正是我所需要的,這有助於我理解這個概念好一點! – Anil

+0

+1,用於擴展方法。我也在我的回答中推薦它。 –

+0

就像一個說明,對於ToolStripStatusLabel&ToolStripProgressBar等StatusStrip控件,應該在StatusStrip上調用包含ToolStrip控件的調用。 – jnoreiga

0

看看這個What is the best way to update form controls from a worker thread? - 它應該解決您的問題。在調用之前

public static class ControlExtensions 
{ 
    public static void Invoke(this Control control, Action action) 
    { 
     if (control.InvokeRequired) 
     { 
      control.Invoke(new MethodInvoker(action), null); 
     } 
     else 
     { 
      action.Invoke(); 
     } 
    } 
} 

現在你可以調用像MyCombo.Invoke(() => { MyCombo.Items.Add(something); }) ---或任何其它控制(如表格),因爲他們都在主線程創建:

1

此異常的,因爲你扔嘗試訪問到被另一個線程創建一個控制成員。在使用控件時,應該只從控件創建的線程訪問控件成員。

控件類可以幫助您瞭解天氣控件在創建線程上是否爲否,以及是否提供InvokeRequeired屬性。所以如果'control.InvokeRequeired'返回true,表明你在不同的線程。幫助你。控制支持InvokeBeginInvoke將處理方法執行到控制主線程的方法。所以:

如果您使用3.5及以上,我建議您使用Eben Roux在他的答案中顯示的擴展方法。

爲2.0:

// This function updates the combo box with the rssData 
private void updateCombo() 
{ 
    MethodInvoker method = new MethodInvoker(delegate() 
    { 
    rssData = getRssData(channelTextBox.Text);  // Getting the Data 
    for (int i = 0; i < rssData.GetLength(0); i++) // Output it 
    { 

     if (rssData[i, 0] != null) 
     { 

      // Cross-thread operation not valid: Control 'titlescomboBox' 
      // accessed from a thread other than the thread it was created on. 

      titlescomboBox.Items.Add(rssData[i, 0]); // Here I get an Error 

     } 
     titlescomboBox.SelectedIndex = 0; 
    } 
    }); 

    if (titlescomboBox.InvokeRequired)//if true then we are not on the control thread 
    { 
     titlescomboBox.Invoke(method);//use invoke to handle execution of this delegate in main thread 
    } 
    else 
    { 
     method();//execute the operation directly because we are on the control thread. 
    } 
} 

,如果您使用C#2.0這個

相關問題