0

オンラインで投稿されたいくつかの例を調べましたが、質問に答えることができません。

forループで1ずつ増加している'p'変数があります。UIに計算の進行状況を表示したい(「p」が0から1000000にどのように増加しているかを示すため)。別のスレッドで計算を行い、ディスパッチャーを呼び出してUIのResultBoxを更新します。例:

 int p=0;

 ...

 private void GO(object sender, System.Windows.RoutedEventArgs e)
 {
        new Thread(delegate()
        {
            DoWork();
        }).Start();

}

    void DoWork()
    {
        for (int i = 0; i < 1000; i++)
        {
            for (int j = 0; j < 10000; j++)
            {
                p++;
                this.Dispatcher.BeginInvoke(delegate { ResultBox.Text = p.ToString(); });
            }
        }

    }

何らかの理由でこれは機能しません。ただし、this.Dispatcherの直前にThread.Sleep(1)を配置すると、意図したとおりに機能します。UIアップデート(ディスパッチャー)が頻繁に呼び出されてフリーズするということですか?それを行う他の方法はありますか?

ありがとうございました

4

2 に答える 2

1

テキストボックスを直接突くのではなく、プロパティをTextBoxにバインドして、プロパティ値を更新してみませんか?

于 2010-07-08T16:10:00.880 に答える
0

はい、ループ内でp ++を実行するだけでは、それほど時間はかかりません。Silverlight内では、Dispatcherはデリゲートを含む単純なキューにすぎません。また、SilverlightがUIを更新して処理する前に、キューに多くの値を送り込んでいます。より高速にキューを追加し続けると、キューがデキューされ、最終的には最大制限に達するとどうなるか想像してみてください。そして最終的にはそれはただ止まるでしょう。p ++をより時間のかかるタスクに置き換えると、良い結果が得られる可能性があります。

私たちの目は通常30fpsの更新しか見ることができないことを知っておく必要があります。1秒あたり30回を超える更新はまったく役に立ちません。最高のパフォーマンスを得るには、ビューの更新を1秒あたり最大10回に減らすことをお勧めします。

そして、進捗状況を示すには、1秒あたり1回の更新でも十分だと思います。まず、常に更新を非常にゆっくりと表示します。

void DoWork() 
{ 
    for (int i = 0; i < 1000; i++) 
    { 
        for (int j = 0; j < 10000; j++) 
        { 
            p++; 
            if((p % 1000)==0){
                 this.Dispatcher.BeginInvoke(delegate 
                      { ResultBox.Text = p.ToString(); });
            } 
        } 
    } 

} 

これで、1000を10の適切な乗数に増減して、視覚的な更新を調整できます。

于 2010-07-08T15:46:53.967 に答える