2011-08-03 53 views
1

我目前正在研究一個Silverlight 4.0應用程序,它在da DataGrid控件中顯示大約13.000行。一個項目包含大約40個字符串屬性和一個整數。頭腦風暴:如何在Silverlight中實現背景計算?

在包含該網格的頁面上,用戶可以設置不同的權重。點擊「更新」按鈕後,Silverlight應根據設置進行一些計算。

在計算過程中,反射被大量使用(和必要)來獲取字符串屬性的值。最後,計算得分並寫入整數字段。這需要爲每個13.000個對象完成。

目前,作爲臨時解決方案,我使用BackgroundWorker實例和Grids Dispatcher(進入UI線程並允許訪問Grid的ItemsSource屬性),遍歷每個項目並計算得分。 此過程需要大約3分鐘,並且太長,因爲用戶不想等待超過幾秒鐘。不幸的是PLinq & Co不包含在Silverlight 4中,甚至我嘗試爲此實現一個多線程解決方案失敗了,因爲我需要回退到UI線程( - > Dispatcher)來更新每個元素(實現INotifyPropertyChanged這是轉發給網格)並訪問ItemsSource。所以,即使使用半並行解決方案,由於依賴於UI線程,它也不是很快。

除了顯示數據之外,用戶需要能夠過濾默認不支持的數據。因此我創建了一個類似於this one的類,該類實現了ICollectionView接口。

你有什麼想法或建議我可以嘗試嗎?

在此先感謝!

回答

2

我的建議是不要在有問題的物體上使用INotifyPropertyChanged或使用ObservableCollection<T>。相反,使用一個簡單的類來表示一個行和普通的舊List<T>來保存該集合。使用CollectionViewSource對象作爲DataGrid.ItemsSource並讓它處理排序。

重新計算時,請先嚐試此操作。切換到後臺線程。創建一個新的List<T>將其容量初始化爲與當前填充的List<T>計數相同。列舉當前的List<T>以執行重新計算,然後添加到新的List<T>中。當所有處理都切換到UI線程並簡單地將新的List<T>分配給CollectionViewSource.Source屬性。

我懷疑這個改變會讓事情足夠快,而不需要編寫任何列表的並行處理。但是,如果你覺得這會有所幫助,那麼包含一些並行處理應該太難了。這種方法的一大優點是僅在完成所有操作時更新UI。

+0

你說得對,它速度很快(我沒有想到它可以這麼快就沒有使用任何並行處理)。謝謝! :) – muffel