2011-08-03 2 views
1

私は現在、DataGridコントロールで約13.000行を表示するSilverlight 4.0アプリケーションを開発中です。 1つのアイテムには、約40の文字列プロパティと1つの整数プロパティが含まれます。ブレインストーミング:Silverlightでバックグラウンド計算を実現する方法は?

グリッドを含むページには、ユーザーがさまざまな重み付けを設定できるパネルがあります。 "更新"ボタンをクリックした後、Silverlightはその設定に応じていくつかの計算を行う必要があります。

リフレクションは、Stringプロパティの値を取得するために頻繁に使用されます(必要になります)。最終的にスコアが計算され、整数フィールドに書き込まれます。これは13.000個のオブジェクトごとに行う必要があります。

現在、私はBackgroundWorkerインスタンスとグリッドディスパッチャー(UIスレッドに入り、グリッドのItemsSourceプロパティにアクセスできるようにする)を使用し、各アイテムを繰り返し、スコアを計算します。 このプロセスには約3分かかり、ユーザーが数秒以上待たないように長すぎます。残念ながら、PLinq & CoはSilverlight 4には含まれていません。さらに、UIスレッド( - > Dispatcher)に戻って各要素を更新する必要があるため、このためにマルチスレッドソリューションを実装しようとしましたが(INotifyPropertyChangedグリッドに転送されます)、ItemsSourceにアクセスします。したがって、セミパラレルソリューションを使用する場合でも、UIスレッドに依存するため、実際には高速ではありません。

データを表示するだけで、ユーザーはデフォルトでサポートされていないデータをフィルタ処理できる必要があります。したがって、私はICollectionViewインターフェイスを実装するthis oneに似たクラスを作成しました。

私は何を試すことができると思いますか?

ありがとうございます!

答えて

2

私の提案では、問題のオブジェクトにINotifyPropertyChangedを使用しないでください。ObservableCollection<T>を使用してください。代わりに単純なクラスを使用して行を表し、普通の古いList<T>を使用してセットを保持します。 DataGrid.ItemsSourceとしてCollectionViewSourceオブジェクトを使用して、そのソートを処理させます。

再計算する場合は、まずこれを試してください。バックグラウンドスレッドに切り替えます。現在実装されているList<T>カウントと同じ容量に初期化する新しいList<T>を作成します。現在のList<T>を列挙して再計算を実行し、新しいList<T>を追加します。すべてが処理されたら、UIスレッドに切り替えて、新しいList<T>CollectionViewSource.Sourceプロパティに割り当てます。

私は、この変更により、リストのすべての並列処理を書く必要がなく、十分迅速に処理できると考えています。しかし、それが助けになると感じるならば、いくつかの並列処理を含めることは難しいはずです。このアプローチの大きな利点は、すべてが完了したときにのみUIが更新されることです。

+0

あなたは正しいですが、かなり高速です(並列処理を一切使用しなくてもそれほど速くないとは思いませんでした)。ありがとうございました! :) – muffel

関連する問題