简体   繁体   English

后台工作程序+套接字中的C#进度栏-进度栏仅在套接字通讯完成后才更新

[英]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. 套接字类没有线程,它将阻塞整个GUI 5秒钟。

Why doesnt this work? 为什么不起作用? and suggestions how I should handle this with GUI. 并建议我应该如何使用GUI处理此问题。

The problem is because the progress bar is being updated by the UI thread. 问题是因为进度条正在由UI线程更新。 But the UI thread is "busy" waiting for the GetDeviceStats function to complete. 但是UI线程“忙”等待GetDeviceStats函数完成。 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. 如果GetDeviceStats函数是一个长期运行的过程(对我来说是这样),那么最好将其纳入后台工作线程中。 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. 一些可能的解决方案是要么在完成时让GetDeviceStats报告进度(我不确定该函数实际做什么,所以这可能不是一个选择),或者如果您需要“伪造”进度,然后使用第二个后台线程或计时器。

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. 就个人而言,我只是将进度条样式设置为“ Marquee”,以便用户知道程序正在忙于做某事,然后在单个后台工作程序上运行GetDeviceStats函数。

Actually, You need two background worker to achieve the GUI working for you with progress bar. 实际上,您需要两个后台工作人员才能使用进度条来实现GUI。 one you already have to update the progress bar. 您已经必须更新进度条。

Second one you can use to call the WebSwitchHandler.GetDeviceStats(NewRoom); 第二个可以用来调用WebSwitchHandler.GetDeviceStats(NewRoom); as async operation so that your UI thread doesn't get blocked. 作为异步操作,以便您的UI线程不会被阻塞。 On completed of this BG worker you can notify the first one to finish immediately rather waiting for a fixed time always. 完成此BG工人的工作后,您可以通知第一个工人立即完成工作,而不必总是等待固定的时间。 This way you can also optimize your wait time. 这样,您还可以优化等待时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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