2012-10-20 86 views
1
  • 我創建視圖模型中的BackgroundWorker的DoWork的內循環對象UI更新
  • 我報告在每個迭代的進展,傳遞新的對象作爲參數傳遞給由ProgressChanged處理程序會獲取(這是用戶界面線程的朋友)
  • 在該處理程序中,該對象被添加到與ListBox綁定的ObservableCollection。

我的ViewModel類包含兩個字符串屬性(Filename和ThumbnailPath),它的DataTemplate包含綁定到這些屬性的Label和Image。BackgroundWorker的執行從一個循環

​​

對於典型的項目數(30-50)的典型行爲:UI凍結約2-3秒;顯示大約一半的項目;用戶界面再次凍結的時間更短,剩下的時間會被添加。

現在我明白從循環中調用UI更新並不是最好的主意 - 我認爲這些調用來得頻繁,UI沒有時間來響應它們,這就是爲什麼我們看到用戶界面被「更新」 「,同時使其無響應。

我試着添加Thread.Sleep(500)作爲循環的最後一行。這幫助我說明了一切正常,因爲在這種放緩的情況下,項目被一個接一個很好地添加沒有任何不響應。

所以我嘗試了不同的睡眠值和結算Thread.Sleep(25)這並不理想,但完全可以接受,並且非常接近應該看起來的樣子。

我想問一下,如果Thread.sleep代碼是像這些情況下的常見解決方法,而且究竟是一般的解決方案的人在這種情況下,去:更新從後臺循環的UI集合,而不根本沒有反應。 我也想出了一些想法,我會很感激你的意見。

想法,我能想到的:

  1. 不要ReportProgress經常 - 它限制在10倍,或每10個 新項目。
  2. 不要在循環中進行。創建需要創建的項目列表 。在DoWork正文中,從列表中取出一個項目, 實例化並返回ViewModel實例。在RonWorkerCompleted上, 更新UI,檢查我們的列表是否爲空,如果不是,則再次運行 RunWorkerAsync。
+0

嘗試使用計時器組件而不是Threed.sleep – Habibillah

回答

1

如果Thread.sleep代碼在以下情況下常見的解決辦法像這些

認爲這是一個不得已而爲之。您正在增加總處理時間(而不是CPU負載)。

1)請勿頻繁報告進度 - 限制爲10次或每10個新項目。

這是基本的想法。收集新物品並通過ReportProgess發送清單。調整列表的大小。

2)不要做成循環。

可能,但你的每Bgw一項看起來要慢很多。它甚至可能顯示相同的症狀。

3)通過ConcurrentQueue解耦。你可以讓DoWork填充一個隊列,一個Dispatcher.Timer可以清空它。也嘗試使用該計時器處理批次。您可以調整計時器的優先級和批量大小。

+0

正是我期待的答案類型。謝謝! :) –

+0

...奇怪的是,通過ReportProgress傳遞10個項目的列表顯示了與以前相同的症狀(當只傳遞一個時)。我開始考慮3),但我懷疑 –

+0

嗯,試試20和50. –