2013-10-03 80 views
0

我在後臺工作線程上調用一個函數,它需要ListBox作爲初始化主線程的參數傳遞。我使用下面的代碼做後臺工作線程中的函數調用只有在主線程執行完成後才能執行?

private void simpleButton1_Click(object sender, EventArgs e) 
    {    
     bw.RunWorkerAsync();   
     GetData()   

    } 
void bw_DoWork(object sender,DoWorkEventArgs e) 
    {   
     this.Invoke(new MethodInvoker(delegate 
     { 
      ShowLoadingPanel(listBox); 
     }));    
    } 

private void GetData() 
     { 
     for (int i = 0; i < 500000; i++) 
     { 
      datatable.Rows.Add(new object[] { "raj", "raj", "raj", i }); 
     } 
    } 

    void ShowLoadingPanel(Control control) 
    { 
     //Doing some work here 
    } 

問題是,ShowLoadingPanel函數調用GetData函數執行完畢之後。我希望這兩個函數在不同的線程中並行運行。

我該怎麼做?

+1

爲什麼使用'BackgroundWorker'如果您在UI線程所有的工作嗎? –

+0

GetData和ShowLoadingPanel都在UI線程上運行。它一次只能做一件事。這裏經典的錯誤是你正在倒退。它應該是你在工作中運行的GetData()。離開UI線程顯示「加載面板」。 –

+0

@HansPassant我知道,做它的逆向會做伎倆。但我的應用程序中沒有網格。我是否需要爲後臺的所有數據檢索來顯示加載面板。這就是爲什麼我正在尋找不同 –

回答

0

您的例子並沒有太大的意義:你想卸載ShowLoadingPanel到另一個(非GUI)線程,但你Control.Invoke執行它被記錄爲在擁有此控件的基礎的線程上執行指定的委託窗戶把手。,即在GUI線程上執行。

Control.Invoke將消息發佈到擁有窗體窗口的線程的消息隊列中,並且您從按鈕Click(它已經作爲消息處理)處理它。因此,只有在您的Click處理程序退出後才能處理髮送到隊列Control.Invoke的消息,這正是您觀察到的情況。

+0

所以我能做兩個函數來模擬運行..因爲我通過列表框作爲參數函數,它會導致異常其他明智的交叉線程異常 –

+0

好吧,你應該只修改控制無論如何,GUI線程,所以你不應該並行做。什麼是慢的部分? –

+0

我需要顯示控制像加載面板,而數據正在填充在winform中。 –

1

試試這個:

private void simpleButton1_Click(object sender, EventArgs e) 
{   
    ShowLoadingPanel(listBox);  
    bw.RunWorkerAsync();  
} 

void bw_DoWork(object sender,DoWorkEventArgs e) 
{   
    GetData(); 
} 

private void GetData() 
{ 
    for (int i = 0; i < 500000; i++) 
    { 
     datatable.Rows.Add(new object[] { "raj", "raj", "raj", i }); 
    } 
} 

void ShowLoadingPanel(Control control) 
{ 
    //Doing some work here 
} 
+0

謝謝Eli,我知道這樣做會正確..但我需要在後臺運行'ShowLoadingPanel'函數! –

+1

您無法更改後臺線程上的UI控件。 –

相關問題