Marquee ProgressBar not responding with BackgroundWorker

In my code, when the button is clicked, the progress bar is installed on the chassis, and then my BackgroundWorker is called, but when the BackgroundWorker is called, the progress indicator freezes or disappears. I am using BackgroundWorker to separate the RefreshReport ReportViewer method from the user interface thread. Any help is appreciated. Thanks!

Private Sub btnOtherReport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOtherReport.Click rvReport.ProcessingMode = ProcessingMode.Remote rvReport.ShowParameterPrompts = False rvReport.ServerReport.ReportServerUrl = New Uri("REPORT_SERVER_URL") rvReport.ServerReport.ReportPath = "REPORT_PATH" rvReport.BackColor = Color.White BackgroundWorker1.RunWorkerAsync() End Sub Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork RefreshReport() End Sub Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted pbReports.Style = ProgressBarStyle.Blocks pbReports.Value = 100 End Sub Public Sub RefreshReport() rvReport.BeginInvoke(New MethodInvoker(AddressOf rvReport.RefreshReport)) End Sub 
+4
source share
2 answers

The problem is that you are calling .BeginInvoke() in your RefreshReport() method. The BackgroundWorker.DoWork() method is already created in another thread, so you can just call rvReport.RefreshReport() . It should look like this:

 Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork rvReport.RefreshReport() End Sub 

It really is that simple, with the possible addition of using Monitor to lock your report object and prevent re-entry.

Right now, when you call .BeginInvoke() , the report process starts, but it does not block at all, so there is nothing left for the DoWork() method. He returns immediately. At this point, BackgroundWorker thinks it's done, so it calls the .RunWorkerCompleted() method, which stops your progress bar.


Based on the comment, rvReport is a visual control, not a component or a simple data access class. In this case, you should be aware that the visual controls in .Net are not thread safe and therefore should never directly do anything directly that takes more than a few minutes. The hoops you passed with .BeginInvoke() in the .BeginInvoke() method had the effect of calling your long-term function in the main user interface thread.

To solve this problem, you need to either disable cross-thread checking so that an exception is not thrown (simple, but not recommended), or your use of the control has changed, so that the main work will happen elsewhere, and the control simply raises events when everything is ready. If you cannot change the control to such an extent, this is a design flaw in the control.

+3
source

The problem is that the progress bar does not get the ability to redraw, while the background processor has a processor. Therefore, you need to call System.Windows.Forms.Application.DoEvents () from the main waiting thread during processing. This will lead to control and cause a redo of the progress bar.

So, after calling BackgroundWorker1.RunWorkerAsync, you can add a loop to call DoEvents until the event is raised, and then raise the event in RunWorkerCompleted to exit the calling code. Since this prevents the main code from continuing to work, you can place the call in a background call or other thread.

-1
source

All Articles