I have a ProgressBar that uses the marquee style when a report is being generated. The reason I am doing this is because the ReportViewer control I use takes some time to generate the report thus making the form unresponsive. I generate the report using a thread so the ProgressBar can show that the program is working. However, when I start the thread the ProgressBar freezes. I have already tried the BackgroundWorker but that didn't work so I used my own threading.
The reason I use the Invoke() method is because I can't make changes to the ReportViewer control on the thread I created because it was created on the UI thread.
The method that takes the most time processing is the RefreshReport() method of the ReportViewer control which is why I'm trying to do that on its own thread instead of the UI thread.
Any help would be appreciated. Thanks.
Here is the code for my thread variable:
Private t As New Thread(New ParameterizedThreadStart(AddressOf GenerateReport))
Here is the code for the button that generates the report:
Private Sub btnGenerateReport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGenerateReport.Click
pbReports.Style = ProgressBarStyle.Marquee
If t.ThreadState = ThreadState.Unstarted Then
t.IsBackground = True
t.Start(ReportType.Roads)
ElseIf t.ThreadState = ThreadState.Stopped Then
t = Nothing
t = New Thread(New ParameterizedThreadStart(AddressOf GenerateReport))
t.IsBackground = True
t.Start(ReportType.Roads)
End If
End Sub
Here is the code that generates the report:
Public Sub GenerateReport(ByVal rt As ReportType)
If rvReport.InvokeRequired Then
Dim d As New GenerateReportCallBack(AddressOf GenerateReport)
Me.Invoke(d, New Object() {rt})
Else
rvReport.ProcessingMode = ProcessingMode.Remote
rvReport.ShowParameterPrompts = False
rvReport.ServerReport.ReportServerUrl = New Uri("My_Report_Server_URL")
rvReport.ServerReport.ReportPath = "My_Report_Path"
rvReport.BackColor = Color.White
rvReport.RefreshReport()
End If
If pbReports.InvokeRequired Then
Dim d As New StopProgressBarCallBack(AddressOf StopProgressBar)
Me.Invoke(d)
Else
StopProgressBar()
End If
End Sub
Your code is starting a new thread from the UI thread. The new thread then immediately marshals back to the UI thread using Invoke - so basically it's as if you hadn't made it multithreaded at all.
Instead of that, make the new thread do all the background processing it can and only marshal back to the UI for parts of the process that need to update the UI.