2017-05-31 6 views
0

クライアントアプリケーションがほぼリアルタイムでサーバーからデータを取得すると仮定します。取得したデータに基づいてUIを継続的に更新する効率的な方法は何ですか?数値を示すテキストのような複数のxamlコントロールを考えてみましょう。アプリケーションが実行されている間は更新されます。ユーザーがそれを決定しない限り、決して停止しません。 (停止ボタンを押すかアプリを終了させる) 以下に、asyncとawaitキーワードを使用した簡単な例を示します。それは私のシナリオのための良い方法ですか?例えば、BackgroundWorkerはもっと良い方法でしょうか?UIを継続的に更新する正しい方法

private async void Button_Click_Begin_RT_Update(object sender, RoutedEventArgs e) 
{ 
    while(true) 
     textField1.Text = await DoWork(); 
} 

Task<string> DoWork() 
{ 
    return Task.Run(() => 
    { 
     return GetRandomNumberAsString(); 
    }); 
} 

*私はコードビハインドではなく使用簡略化のために私の例では

+0

私はWPFを使用しますが、私はしたDependencyPropertyへの結合が行く方法だと思っているだろうので、それはしばらくしています。これらの2つの投稿は正しい方向にあなたをシャントする必要があります:https://stackoverflow.com/questions/19981966/wpf-xaml-binding-to-object-created-in-code-behind、https://stackoverflow.com/questions/5824600/databind-xamlからコードビハインドへ –

+1

WPFの背後にあるコアアイデアは、データバインディングとビューモデルクラスを使用しているため、コードの背後で直接コントロールを呼び出すことはありません。したがって、私があなたの場合は、ビューモデルクラスを作成し、 'INotifyPropertyChanged'インターフェースを実装し、プロパティを関連するコントロールにバインドし、async' Task'sを使用してviewmodelクラスインスタンスを更新します。 – mcy

+0

簡潔にするために@mcy私はMVVMに基づいて自分のコードを書いていませんでした。しかし、私は自分のプロジェクトでmvvmを使用します。 – gts13

答えて

2

をMVVMあなたGetRandomNumberAsString()が完了するまでに少なくとも15ミリ秒で取る場合あなたのコードは、多かれ少なかれOKです。

これよりも時間がかからず、更新待ち時間を最小限に抑えたい場合、つまり、(1)操作ごとにTask.Runを完全に実行するエンドレスループに置き換えることができます。バックグラウンドスレッド(2)そのループでスロットリングメカニズムを実装し、約30-60HzでGUI(例:Dispatcher.BeginInvoke()など)を更新するだけです。

P.S.あなたのGUI(databinding + INotifyPropertyChanged、またはあなたのコードに直接似ている)を更新する正確な仕組みは、パフォーマンスには関係ありません。

アップデート:ここでの例(未テスト)です

static readonly TimeSpan updateFrequency = TimeSpan.FromMilliseconds(20); 
void ThreadProc() 
{ 
    Stopwatch sw = Stopwatch.StartNew(); 
    while(true) 
    { 
     string val = GetRandomNumberAsString(); 
     if(sw.Elapsed < updateFrequency) 
      continue; // Too early to update 
     sw.Restart(); 
     Application.Current.Dispatcher.BeginInvoke(() => { textField1.Text = val; }); 
    } 
} 
+0

いくつかのサンプルコードやリンクを用意してください。特に、 "そのループのスロットルメカニズム"は少し難解です。 – gts13

+0

私は75Hzモニターを持っています。 144Hzのモニターを持つ人もいます。理想的には、UIはすべてのペイントサイクルを更新します。 –

+0

@IanBoyd非常にレイテンシに敏感なアプリケーションの場合、CompositionTarget.Renderingは本当に優れています。しかし、正しく実装するのは難しいです。イベントはフレームごとに複数回呼び出される可能性があり、以前の呼び出しからデータが変更された場合にのみGUIを更新する必要があります。ほとんどのアプリでは、30〜50Hzのスロットル調整が問題ありません。 – Soonts

関連する問題