我有一个ProgressBar,它在生成报告时使用选框样式。我之所以这样做是因为我使用的ReportViewer控件需要一些时间来生成报表,从而使表单无响应。我使用一个线程生成报告,因此ProgressBar可以显示该程序正在运行。但是,当我启动线程时,ProgressBar会冻结。我已经尝试过BackgroundWorker,但是没有用,所以我使用了自己的线程。
我使用Invoke()方法的原因是因为我无法在我创建的线程上对ReportViewer控件进行更改,因为它是在UI线程上创建的。
花费大部分时间处理的方法是ReportViewer控件的RefreshReport()方法,这就是我试图在自己的线程而不是UI线程上执行此操作的原因。
任何帮助将不胜感激。感谢。
以下是我的线程变量的代码:
Private t As New Thread(New ParameterizedThreadStart(AddressOf GenerateReport))
以下是生成报告的按钮的代码:
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
以下是生成报告的代码:
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
答案 0 :(得分:2)
您的代码正在从UI线程启动一个新线程。然后新线程立即使用Invoke回调到UI线程 - 所以基本上就好像你根本没有使用多线程一样。
而不是这样,让新线程完成它可以进行的所有后台处理,并且只为需要更新UI的部分进程编组回UI。
答案 1 :(得分:0)
您可以尝试使用ThreadPool生成新的工作线程。我在WPF应用程序中使用下面的代码来显示超过4秒左右的任何内容的加载屏幕。
您可能需要更改一些语法,因为我是C#家伙......
Private Sub btnGenerateReport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGenerateReport.Click
pbReports.Style = ProgressBarStyle.Marquee
ThreadPool.QueueUserWorkItem(Function(th) Do
GenerateReport(ReportType.Roads)
Dispatcher.BeginInvoke(DispatcherPriority.Normal, DirectCast(Function() Do
StopProgressBar()
End Function, Action)
End Function)
End Sub
另外,我相信Dispatcher.BeginInvoke仅在WPF中,而不在WinForms中,所以我需要将其更改回Me.Invoke或其他内容。