2013-05-11 109 views
0

我創建了一個backgroundWorker,我在Google上搜尋後然而,通過堆棧溢出調用InitializeComponent()RunWorkerAsync,我才知道,我無法通過DoWork我更新UI要做到這一點在RunWorkerCompletedBackgroundWorker的更新UI掛起​​由於大量的數據負載

所以我這樣做,但我的問題是我創造的DoWork一個大的數據表,這樣我可以通過RunWorkerCompleted填補我的網格數據,但這樣做的一切之後,當它進入RunWorkerCompleted我應用程序掛起幾秒鐘,然後在加載後恢復。

我覺得這是發生的,因爲我通過DoWork獲取了很多數據,當我使用RunWorkerCompleted來顯示它掛起的數據時。

我有大約50,000數據,我從數據庫中提取。

如何解決此問題。也許我可以使用和做這些東西,除了BackgroundWorker還有什麼辦法。或者可能通過BackgroundWorker只有我可以做一些調整,它運作良好。

+0

爲什麼不能從'DoWork'更新UI? – PoweredByOrange 2013-05-11 05:31:41

+0

@ programmer93這是可能的。正如我那樣做,它說'非法跨線程操作:控制'myTextBox'從一個線程訪問,而不是它創建的線程。'我衝浪並知道不允許從'DoWork'更新UI更新 – 2013-05-11 05:41:37

+0

請參閱下面的答案。 – PoweredByOrange 2013-05-11 05:59:57

回答

0

您絕對可以從DoWork方法中更新UI。你說你在註釋部分得到的錯誤是因爲只有擁有控件的線程才允許修改它。但是,其他線程也可以進行修改,但它們需要將其包裝在一個代理中,以使操作線程安全。在你DoWork方法,只要你想更新控制,遵循以下步驟:

if (this.InvokeRequired) 
{ 
    this.Invoke((MethodInvoker)delegate() 
    { 
    // Update the UI here. For example: 
    // myTextBox.Text = "Hello World!"; 
    }); 
} 
+0

我相信這仍然會阻止UI線程。也許如果他以更小的數據塊添加數據,它將不太明顯。不過,我可能會將記錄數量限制在一個更易於管理的數量。 – JosephHirn 2013-05-11 06:29:14

+0

好的是,添加小塊數據是關鍵。我不知道他使用的數據類型是什麼,但是讓我們說100個應該做​​的伎倆。無論如何,當工作完成時,它還是比一次提供UI的所有數據更好。 – PoweredByOrange 2013-05-11 06:32:28

+0

@ programmer93感謝您的回答,我只是試一試... – 2013-05-11 07:13:46

0

對不起,我知道這個線程是舊的,但我也有類似的問題,發現了不同的解決方案不要求對Invoke顯式調用。它基於這樣的事實,即ProgressChanged事件通過報告某種類型的指示BG工作人員未被凍結或卡住來更新UI(幾乎)。

確保您的BackgroundWorker.WorkerReportsProgress=true並且還爲ProgressChanged事件添加事件處理程序。

現在來的魔力,當你彙報進展,它需要一個百分比int(類型object的可選UserState參數一起),但不檢查值是在任何特定的範圍內。所以,當我彙報進度百分比從0100,進度更新(例如24%完成),但是當我發送範圍之外的數字,別的東西「更新」:

DoWork方法:

... 
this._BG_Worker.ReportProgress(-1); 
this._BG_Worker.ReportProgress(-2, "Reading NAND"); 
... 
this._BG_Worker.ReportProgress((int)(100.0 * a/b), string.Format("{0}/{1} bytes", a, b)); 
... 

ProgressChanged事件處理程序:

if (e.ProgressPercentage>=0 && e.ProgressPercentage<=100) 
    this.tsslMain.Text=string.Format("{0}% done ({1})", e.ProgressPercentage, e.UserState); 
else switch (e.ProgressPercentage) 
{ 
    case -1: 
     this.lbStatus.Items.Clear(); 
     break; 
    case -2: 
     if (e.UserState!=null && e.UserState is string) 
      this.lbStatus.Items.Add(e.UserState as string); 
     break; 
    case ... 
} 

所以這裏。