2011-01-18 20 views
8

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

Iは、メインウィンドウのコンストラクタでユーザーコントロールを構築(およびすべてのデータロードを行う)試み:
スプラッシュ画面がアプリケーションになるまで空のメインウィンドウの1S、続いて次に、このよう5S示されます使用する準備ができました。
ユーザーは、何か(視覚的に)発生するまでに時間がかかりすぎると言いました。

次に、メインウィンドウのLoadedイベントハンドラにユーザーコントロールの作成(およびデータ読み込み)を移動しました。 スプラッシュ画面が3秒表示され、メインウィンドウが3秒表示され、アプリケーションが準備完了になります。
ユーザーは「より良い」と言いましたが、半分になったメインウィンドウが長い間無効な状態で表示されているということは嫌です。

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

誰でもこの問題の提案がありますか?

編集:
今は、グリッドデータソースとしてLINQ-to-EFクエリを割り当てたことに注意してください。
一つの可能​​な改善が

EDIT2 ...バックグラウンドでデータテーブルにこのデータをロードし、一度だけロードされ、それを割り当てることがあります。 私はロードするためにSystem.Data.SQLiteとEF4による.NET 4を使用していますデータ。多かれ少なかれ4000行と30列あります。

+0

データベースからどれだけのデータをロードしていますか?あなたはどのようにデータをロードしていますか?ORM(もしあれば?)またはプレーンなADO.NETを使用していますか? – alimbada

+0

多くのことが起こっていることをユーザーに伝えます。実際に何が起こっているかをチェックし、それに応じて最適化してください。ログイン画面や拡張スプラッシュ(波状のアニメーション/プログレスバー付き)は、まさに彼らが探しているものかもしれません。 – CodingBarfield

+0

@alimbada:この情報を含めるように質問を編集しました。しかし、それはエンティティフレームワークなどに関連するよりも一般的な質問です.ADO.NETやORMはデータをロードするのに時間がかかりますが、これをThread.Sleep(..)に置き換えることもできます。問題はこのような状況にどう対処するかです。 – Marc

答えて

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は非常に高速です。コントロールの作成に時間がかかりません。私は数ミリ秒で言及するように、はるかに大きなリストを視覚化します。

UIでDataGridがアイテムを仮想化するのを妨げるものがあるかどうかを調べてみてください。多分あなたはそこに賛美歌を持っています。 WPFアプリを分析するには、WPF Profiling Toolsをお勧めします。

+0

また、これがSilverlightの機能です。 (別の構文、同じ原理です。) –

+0

はい、それは今まで私が遅い操作をどのように処理したのか、それはかなりうまく機能しました。唯一の問題は、bgWorker.RunWorkerAsync()を呼び出す前にUIを無効にする必要があることです。そうしないと、ユーザーを混乱させる可能性があります。 – Marc

+1

@Marc:はい、ただし、UIの一部だけを無効にすることができます。これはユーザーにとって素晴らしい体験です。私が書いたように、データがうまくいけば、読み込まれた最初のいくつかのレコードやファイルを提示して、ユーザーがすでにそれらのレコードを操作できるようにすることもできます。しかし、これらのすてきなものはすべて開発時間にかかり、物事をより複雑にします。問題は、クライアントがプロジェクトの費用を負担し、プロジェクトの複雑性を察知することが理にかなっている場合です。 – HCL

2

あなたができる最も明白なことは、アプリケーションのプロファイルを作成し、起動時にボトルネックを見つけることです。あなたのデータベースからのデータ読み込みの可能性が最も高いと思われます。

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

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

例:

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

return query.ToList(); 

POCOS各フィールドのautopropertiesと非常に単純なクラスです。

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

+0

+1です。私はアプリケーションをプロファイルしました。それは私が改善することができない本当に多かれ少なかれ3秒アプリ(およびフレームワーク)の初期化です。他の3つはユーザーコントロールの作成とデータ読み込みから来ています。また、基本的なADO.NETデータリーダーを使用してパフォーマンスを向上させることも考えました。 – Marc

+0

バックグラウンドでのデータロードの処理方法を示しているMVVMの例へのリンクはありますか?読み込み中にビューで何をやっているのですか? – Marc

+0

申し訳ありませんが、手元にオンラインの例はありません。それは私が同僚から学んだものです。私は自分の例を加え、私の元の答えに少し精緻化しました。私たちが現在取り組んでいるアプリケーションでは、最初にロードするのに1分30秒かかったので、私はそれが動作することを個人的に保証することができます。今は10秒未満です。私たちは、起動時にSQL Server DBから300kから400kの読み込みをしています... – alimbada

0

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

1)デプロイメントマシンの構成がかなり低い可能性があります。
2)In-Properまたはデータバインドの問題。

可能な解決策は次のようになります
1)遅延データ
2)パフォーマンスの最適化を読み込みます。 http://msdn.microsoft.com/en-us/library/aa970683.aspx

私は、アプリケーションが5Mレコードをwpfで1秒未満でレンダリングしました。

PS:1つ以上の考えられる理由は、列の順序のアクセスのために30列である可能性があります。

関連する問題