8

私は WPF データベース ビューアー アプリケーションを持っています。これは、SQLite データベースから抽出されたデータを表示するデータ グリッドを備えたユーザー コントロールを含む単純なメイン ウィンドウです。
問題は、このアプリケーションが使用可能になるまで、起動に 6 秒かかることです。

メイン ウィンドウのコンストラクターでユーザー コントロールを作成 (およびすべてのデータの読み込み) を試みました
。スプラッシュ スクリーンはこのように 5 秒間表示され、その後、アプリケーションを使用する準備が整うまで、空のメイン ウィンドウが 1 秒間表示されます。
ユーザーは、何かが (視覚的に) 起こるまでに時間がかかりすぎると言っています。

次に、ユーザー コントロールの作成 (およびデータの読み込み) をメイン ウィンドウの Loaded イベント ハンドラーに移動しました。スプラッシュ スクリーンが 3 秒間表示され、その後、アプリケーションの準備が整うまで 3 秒間空のメイン ウィンドウが表示されます。
ユーザーはそれが「より良い」と述べましたが、半分完成したメインウィンドウが長い間無効な状態で表示されるという事実が好きではありません.

認識されたアプリケーションの読み込み時間に関する一般的なアドバイスはありますか、またはこの状況を改善する方法について他の推奨事項はありますか?
理想的には、データが読み込まれるまで、砂時計またはスピナーとともに、メイン ウィンドウができるだけ速く表示されると思います。しかし、これは間違ったスレッドで行われるため、ユーザー コントロールの作成をバックグラウンド ワーカーに移動することはできません。

この問題に対する提案はありますか?

編集:
現時点では、グリッド データ ソースとして LINQ-to-EF クエリを割り当てただけであることに注意してください。
考えられる改善の 1 つは、このデータをバックグラウンドでデータ テーブルに読み込み、読み込まれたときにのみ割り当てることです...

Edit2: System.Data.SQLite および EF4 で .net 4 を使用してデータをロードしています。およそ 4000 行と 30 列があります。

4

3 に答える 3

13

データを非同期でロードします。ロード中にユーザーにGUIで何かいいものを提示します。次のコードはこれに役立ちます:

BackgroundWorker bgWorker = new BackgroundWorker() { WorkerReportsProgress=true};  
bgWorker.DoWork += (s, e) => {      
    // Load here your file/s      
    // Use bgWorker.ReportProgress(); to report the current progress  
};  
bgWorker.ProgressChanged+=(s,e)=>{      
    // Here you will be informed about progress and here it is save to change/show progress. 
    // You can access from here savely a ProgressBars or another control.  
};  
bgWorker.RunWorkerCompleted += (s, e) => {      
// Here you will be informed if the job is done. 
// Use this event to unlock your gui 
};  
bgWorker.RunWorkerAsync();  

アプリは高速ではありませんが、GUIがすぐに表示されて応答するため、はるかに高速のようです。おそらく、ロードされたデータの一部をユーザーに表示し、残りをロードすることもできます。ProgressChangedこれを行うには、-eventを使用します。

アップデート

あなたの問題を正しく理解しているかどうかはわかりません。問題がデータをロードする必要がある時間ではない場合、アプリケーションに何か奇妙なことがあります。WPFはIMOが非常に高速です。コントロールの作成にはそれほど時間はかかりません。あなたが数ミリ秒で言及するように、私ははるかに大きなリストを視覚化します。

DataGridがアイテムを仮想化するのを妨げる何かがUIにあるかどうかを調べてみてください。多分あなたはそこに問題を抱えています。WPFアプリを分析するために、WPFプロファイリングツールをお勧めします。

于 2011-01-18T13:52:27.530 に答える
2

できる最も明白なことは、アプリケーションをプロファイリングして、起動時のボトルネックを見つけることです。最も可能性の高い原因は、データベースからのデータの読み込みです。

私が学んだ教訓の 1 つは、ORM を使用している場合、大規模なデータセットを読み込むときに、ORM で生成されたデータベース エンティティよりも POCO (Plain Old CLR/C# Objects) を好む場合 (以下の例を参照)、読み込み時間ははるかに高速になり、RAM の使用量も大幅に減少します。この理由は、EF がエンティティ全体 (つまり、そのすべてのフィールド) を読み込もうとするためです。おそらく、エンティティに関連するデータ全体を読み込もうとしますが、そのほとんどは必要ありません。エンティティを実際に直接操作する必要があるのは、挿入/更新/削除操作を行っているときだけです。データを読み取るときは、アプリケーションが表示および/または検証する必要があるフィールドのみを取得する必要があります。

MVVM パターンに従えば、上記のアーキテクチャを実装するのは難しくありません。

EF を使用してデータを POCO にロードする例:

var query = from entity in context.Entities
                select new EntityPoco
                {
                    ID = entity.ID,
                    Name = entity.Name
                };

return query.ToList();

POCO は、各フィールドの自動プロパティを持つ非常に単純なクラスです。

通常、アプリケーション内のエンティティごとにリポジトリがあり、各リポジトリはそのエンティティに関連するデータの取得/更新を担当します。ビュー モデルには必要なリポジトリへの参照があるため、EF を直接使用しません。ユーザーが永続化する必要がある変更を行った場合、エンティティのサブセット (ユーザーが変更したもの) のみをロードし、必要な更新を適用するリポジトリ内の他のメソッドを使用します。制約/トリガーなどを介して DB で実行されます。

于 2011-01-18T14:04:44.020 に答える
0

これには多くの理由があります。

1) 展開マシンの構成がかなり低い可能性があります。
2) データ バインディングの不適切または問題。

考えられる解決策は次のとおりです
。1) データの遅延ロード
2) パフォーマンスの最適化。http://msdn.microsoft.com/en-us/library/aa970683.aspx

アプリケーションが wpf で 5M レコードを 1 秒未満でレンダリングするのを見たことがあります。

PS:もう 1 つの考えられる理由として、列の順序によるアクセスのため、30 列が考えられます。

于 2011-01-18T18:26:45.020 に答える