0

バックグラウンド ワーカーの進行状況バーの問題に直面しています。

public void UpdateDevices(object sender, EventArgs e) {
     bw_1.RunWorkerAsync();
     Thread.Sleep(100);
     WebSwitchHandler.GetDeviceStats(NewRoom); 
    //Above line opnes a socket and takes 5 seconds to return back//
}

private void bw_1_DoWork(object sender, DoWorkEventArgs e)
{
   for (int i = 1; i <= 100; i++)
   {
      Thread.Sleep(100);
      bw_1.ReportProgress(i);
   }
} 
private void bw_1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

プログレス バーは、ソケットが返された後にのみ更新されます。ソケット クラスにはスレッドがなく、GUI 全体が 5 秒間ブロックされます。

なぜこれが機能しないのですか?GUIでこれを処理する方法を提案します。

4

2 に答える 2

1

問題は、プログレス バーが UI スレッドによって更新されているためです。GetDeviceStatsしかし、UI スレッドは関数が完了するのを待って「ビジー」です。そのため、再びフリーになるまでプログレス バーの更新を処理できません。

関数が長時間実行されるプロセスである場合GetDeviceStats(私にとってはそうです)、その作業をバックグラウンド ワーカー スレッド内に含めるのが最適です。ただし、通話が再び終了するまで、進行状況を報告することはできません (したがって、進行状況バーを更新することもできません)。

それに対するいくつかの可能な解決策は、GetDeviceStats完了時に進行状況を報告することです(その機能が実際に何をするのかはわからないので、これはオプションではないかもしれません)、または進行状況を「偽造」する必要がある場合は、2番目の背景を使用しますスレッドまたはタイマー。

個人的には、進行状況バーのスタイルを「マーキー」に設定して、ユーザーがプログラムが何かを実行中であることを認識してGetDeviceStatsから、単一のバックグラウンド ワーカーで関数を実行します。

于 2013-07-29T13:03:01.737 に答える
0

実際には、進行状況バーで GUI が機能するようにするには、2 つのバックグラウンド ワーカーが必要です。プログレスバーを更新する必要があります。

WebSwitchHandler.GetDeviceStats(NewRoom);UI スレッドがブロックされないように、as async 操作を呼び出すために使用できる 2 番目のもの。この BG ワーカーが完了すると、常に一定の時間を待つのではなく、最初のワーカーにすぐに終了することを通知できます。このようにして、待ち時間を最適化することもできます。

于 2013-07-29T13:34:54.687 に答える