在我的代码中,当单击按钮时,进度条设置为选取框,然后调用我的BackgroundWorker,但是当调用BackgroundWorker 时,进度条会冻结或消失。我使用BackgroundWorker 将ReportViewer 的RefreshReport 方法与UI 线程分开。任何帮助表示赞赏。谢谢!
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
问题是当你打电话时.BeginInvoke()
在你的RefreshReport()
方法。这BackgroundWorker.DoWork()
方法已经在不同的线程中引发,因此您只需调用rvReport.RefreshReport()
。它应该看起来像这样:
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
rvReport.RefreshReport()
End Sub
确实就是这么简单,可以添加使用Monitor
锁定您的报告对象并防止重新进入。
现在,当你打电话时.BeginInvoke()
报告过程开始,但它根本不会阻塞,所以没有什么可做的DoWork()
方法去做。它立即返回。此时BackgroundWorker认为已经完成,因此调用.RunWorkerCompleted()
方法,它会停止你的进度条。
根据评论,rvReport
是一个可视控件,而不是一个组件或简单的数据访问类。在这种情况下,您应该知道 .Net 中的可视控件不是线程安全的,因此应该never直接做任何需要花费几分钟才能完成的事情。你跳过的圈圈.BeginInvoke()
in the RefreshReport()
方法具有调用长时间运行的函数的效果在主 UI 线程中.
要解决此问题,您需要关闭跨线程检查,以便不引发异常(简单,但不推荐),或者更改使用控件的方式,以便主要工作发生在其他地方,并且控件仅在以下情况下引发事件:事情已经准备好了。如果您无法将控件修改到那种程度,则说明控件存在设计缺陷。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)