2012-10-25 5 views
5

2つのプログレスバーと1つのバックグラウンドワーカーを持つシンプルなフォームがあります。私は2つのループ(1つは他のものの中にある)を持っています。そして、私は増分した各ループの進捗状況を報告したいと思います。BackgroundWorkerで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の値が変更されていることがわかります。変化はありません。何か案は?

+0

プログレスバーの最大値は正しく設定されていますか? –

+0

@lc。はい、デフォルトでは100に設定されていますが、2回目のループカウンタの合計が500になるように変更しました。 – Robert

+1

500のループは非常に高速になります。それは更新されているようには見えないかもしれません。内側のループにThread.Sleep()を追加してみて、それが本当に素早く起こっているかどうかを見てみてください。 –

答えて

5

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

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

これには副作用があります。このアニメーションを機能させるには、プログレスバーは遅れでなければなりません。つまり、常にの値をの後ろに表示しています。バーの長さをプログラムされた値にスムーズに増加させるには、ある程度の時間が必要です。あなたはすぐにバーの長さをジャンプ Valueプロパティを、減少とき、このアニメーションはは発生しません:あなたが知っている必要があり

一つの詳細。

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

にそれを作ることはできないほど高いです:あなたは増やす必要があるかもしれません引数の値を持つ

System.Threading.Thread.Sleep(1); 

プレイ、それは16に任意の違いを参照してください。あなたがそれを高くするほど、バーは補間によってそれを作ります。

これは実際の問題ではありません。これは、あなたの作業者が実際の作業をしていないためです。このBGWが行うはずの実際のコードを書き始めると、ProgressChangedを呼び出すレートも低下します。

+0

この詳細な回答をありがとう、私は多くを学んだ。この問題に対する最良のアプローチは何ですか? – Robert

+1

私はそれについて明示していました、最後の段落。 –

1

問題は、内側のループがきつすぎるためにguiのアップデートが頻繁に送信されているため、guiが正確に応答することができません。解決策は、内側のループに実際の作業を追加することです。時間がかかります。また、GUIをシミュレートする場合は、Thread.Sleep(100)を追加して、時間をかけて作業をシミュレートすることもできます。

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

0

あなたの主な問題は、内部ループが速すぎることに由来します。つまり、更新が速すぎて処理が進まないため、進行状況を実際に見ることができません。コードの

あなたの行:あなたはとてもその番号にも関係していない500に設定するプログレスバーの最大値を持つ、内側のループを終了するとき

location * 100/500 

が100に等しくなります。これは、プログレスバーが決して最大値に達しないことを意味します。

関連する問題