2011-12-17 10 views
1

私はWPF &のC#アプリケーションで、頻繁に変化する値の束を監視するために、約35列×50行の大きなDataGridを含んでいます。問題は、グリッド全体が表示されているときに、それをリフレッシュすると、ほぼ1秒間ユーザーインターフェイスがハングアップするということです。明示的に2秒ごとにリフレッシュしますが、これは私がやっていることでうまくいきますが、残りのUIをハングアップさせるのは本当の苦痛です。マルチスレッド、マルチディスパッチャーWPFアプリケーションはまだ1つのスレッドで描画しますか?

OKだから、私はUIの残りの部分を独立したディスパッチャーを持つ別のスレッドの別のウィンドウで実行すると決めました。 DispatcherTimerを使って1秒に10回更新するインクリメントカウントを持つtextBlockを含むおもちゃウィンドウを作成しました。しかし、カウントがスムーズにインクリメントするのではなく、グリッドがリフレッシュされている間に一時停止し、の表示を再開し、カウント数はを一時停止したときより約10高くなり、タイマーイベントが処理されます。私はちょうどリフレッシュを見ていないよ。

WPFは、すべての要素を1つのスレッドに描画しますか?それのまわりで何か?

は、ここに私の第二のウィンドウを作成するコードです:

private void Window_Loaded(object sender, RoutedEventArgs e) 
{ 
    ThreadStart ts = new ThreadStart(RunSpareThread); 
    m_spare_thread = new Thread(ts); 
    m_spare_thread.IsBackground = true; 
    m_spare_thread.Priority = ThreadPriority.Highest; 
    m_spare_thread.SetApartmentState(ApartmentState.STA); 
    m_spare_thread.Start(); 

    Dispatcher.Thread.Priority = ThreadPriority.Lowest; 
} 

void RunSpareThread() 
{ 
    m_spare_window = new SpareWindow(); 
    m_spare_window.Show(); 
    Dispatcher.Run(); 
} 

はFYI私は、グリッドを実装するいくつかの異なる方法試してみた - リストビューなど、OnRenderをオーバーライドし、GlyphRunDrawingsの全体の束を描くキャンバスとして - WPFをこのようなことを描くのは非常に遅いです。

答えて

3

残念ながらはいです。それはあなたのあなたの応答性を高めるためにあなたができることの数があると言いました。主なものの1つは、UIスレッドで最小限の作業が行われていることを確認することです。これは、別の文脈の中でDB読書等のすべてを行うことを意味する。また、グリッドがあなたの価値をどのように表示しているかを調べる必要があります - それは仮想化ですか?次に、データバインディングの方法もあります。バインディングソースでは、すべての変更が完了した後でのみバインディングを更新できます。

1

WPFは、正しく使用すると非常に高速です。

いくつかのヒント:

  1. MVVMの観点やViewModelに)モデルを実装し、表示したいデータの。それがINotifyPropertyChangedインターフェイスを実装していることを確認してください。そのようなモデルのコレクションをDataGridにバインドします。
  2. N秒ごとにすべてのデータを更新しないでください。何らかの形でデータ変更を検出し(適切なスレッドを使用して)、適切なモデルの適切なプロパティを更新する必要があります。データバインディングのため、すべての変更がDataGridに自動的に反映されます。したがって、少なくとも明示的にはDispatcherを使用する必要はありません。
  3. データで特別な操作(編集、並べ替え、フィルタリングなど)を行う必要がない場合は、DataGridの代わりにListViewを使用してください。
  4. 膨大な量の行を表示する必要がある場合は、virtualizationの実装を検討してください。
関連する問題