2009-01-08 93 views
0

我有一個ProgressBar在生成報表時使用了選取框樣式。我這樣做的原因是因爲我使用的ReportViewer控件需要一些時間來生成報表,從而導致表單無響應。我使用線程生成報告,以便ProgressBar可以顯示程序正在工作。但是,當我啓動線程時,ProgressBar會凍結。我已經嘗試過BackgroundWorker,但那不起作用,所以我使用了自己的線程。當使用多線程時ProgressBar凍結

我使用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 

回答

2

您的代碼正在從UI線程開始一個新線程。然後新的線程立即用Invoke編組回到UI線程 - 所以基本上就好像你沒有完成多線程一樣。

取而代之的是,讓新線程執行所有可以進行的後臺處理,並且僅將需要更新界面的部分進程回送到用戶界面。

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之類的東西。