简体   繁体   中英

C# Progress Bar in background worker + Socket - Progress bar only updates after socket comm is done

I am facing an issue with progress bar in background worker.

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;
}

The progress bar updates only after the socket has returned. The socket class has no threads, it blocks the entire gui for the 5 seconds.

Why doesnt this work? and suggestions how I should handle this with GUI.

The problem is because the progress bar is being updated by the UI thread. But the UI thread is "busy" waiting for the GetDeviceStats function to complete. So it cannot handle the progres bar update until it becomes free again.

If the GetDeviceStats function is a long running process (which to me it is) then you would be best including that work within you background worker thread. However, you still wont be able to report the progress (and therefore update the progress bar) until the call has once again finished.

Some possible solutions to that would be to either have GetDeviceStats report progress as it completes (I am not sure what that function actually does, so this may not be an option), OR if you need to "fake" the progress then use a second background thread or a timer.

Personally, I would just set the progress bar style to "Marquee" so the user knows the program is busy doing something, and then run the GetDeviceStats function on a single background worker.

Actually, You need two background worker to achieve the GUI working for you with progress bar. one you already have to update the progress bar.

Second one you can use to call the WebSwitchHandler.GetDeviceStats(NewRoom); as async operation so that your UI thread doesn't get blocked. On completed of this BG worker you can notify the first one to finish immediately rather waiting for a fixed time always. This way you can also optimize your wait time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM