6

2 つのプログレスバーと 1 つのバックグラウンドワーカーを含む単純なフォームがあります。私は 2 つのループ (1 つが他のループ内) を持っており、インクリメントされた各ループの進行状況を報告したいと思います。ここに私が持っているコードがあります:

private void buttonStart_Click(object sender, EventArgs e)
{
    workerCustomers.RunWorkerAsync();
}

private void workerCustomers_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
    progressBar2.Value = (int)e.UserState;
}

private void workerCustomers_DoWork(object sender, DoWorkEventArgs e)
{
    for (int customer = 0; customer < 50; customer++)
    {
        int customerPercentage = ++customer * 100 / 50;
        workerCustomers.ReportProgress(customerPercentage, 0);

        for (int location = 0; location < 500; location++)
        {
            int locationPercentage = ++location * 100 / 500;
            workerCustomers.ReportProgress(customerPercentage, locationPercentage);
        }

        workerCustomers.ReportProgress(customerPercentage, 0);
    }
}

プログラムが実行されると、progressbar1 は正常に更新されますが、progressbar2 は移動しません。デバッガーで実行すると、progressbar2 の値が変更されていることがわかります。グラフィカルに変更はありません。何か案は?

4

3 に答える 3

6

はい、デスクトップで Aero が有効になっている場合、2 番目のプログレス バーは更新されません。これはアニメーション化された進行状況バーを提供します。これはデフォルトで緑色で、移動中のハイライト ノートが付いています。

このプログレス バーのスタイルは特別で、コース値を Value プロパティに割り当てても、中間値を補間し、常に滑らかに見えます。つまり、10、20、30 などを割り当てることができますが、バーはジャンプしません。バーの長さをスムーズに伸ばします。

これには副作用があります。このアニメーションを機能させるには、プログレス バーが遅れる必要があります。つまり、常にプログラムされた値よりも遅れた値を示しています。そして、バーの長さがプログラムされた値までスムーズに増加するには、しばらく時間がかかります。

知っておく必要があるもう 1 つの詳細: このアニメーションは、Value プロパティを減らすと発生せず、すぐにバーの長さがジャンプします。

したがって、問題は、バーが補間できるよりもはるかに高速で、非常に高いレートで Value プロパティを更新していることです。それは決して追いつくことはできません。0 から再起動する場合を除き、すぐにバーがジャンプします。レートが非常に高いため、アニメーションが 1 になることはありません。

これは、内側のループ内に次のステートメントを挿入することで確認できます。

   System.Threading.Thread.Sleep(1);

引数の値をいじってみてください。違いを確認するには、値を 16 に増やす必要があるかもしれません。高くするほど、補間によってバーが遠くなります。

もちろん、これは実際の問題ではありません。これは、ワーカーが実際の作業を行っていないために発生します。この BGW が実行するはずの実際のコードを書き始めるとすぐに、ProgressChanged を呼び出す速度も低下します。

于 2012-10-25T11:08:18.567 に答える
1

問題は、内部ループが非常にタイトで、GUI の更新が頻繁に投稿されて、GUI が正確に応答できないという事実にあります。解決策は、実際の作業を内側のループに追加することです。そのため、時間がかかります。または、GUI をシミュレートする場合は、Thread.Sleep(100)時間をかけて作業をシミュレートするために a を追加するだけです。

また、プログレス バーの最大値が 100 に設定されていることを確認してください。これは、それぞれに対して返される最大値です。

于 2012-10-25T10:51:42.730 に答える
0

主な問題は、進行状況バーが処理するには更新が速すぎるため、進行状況を実際に確認できないことを意味する、速すぎる内部ループに起因します。

あなたのコード行:

location * 100 / 500 

内側のループが終了すると 100 になるため、プログレスバーの最大値を 500 に設定しても、その数値とはあまり関係がありません。プログレスバーが最大値に達しないことを意味します。

于 2012-10-25T11:26:13.070 に答える