Marquee ProgressBar 对 BackgroundWorker 无响应

发布于 2024-07-10 18:11:30 字数 1242 浏览 8 评论 0原文

在我的代码中,当单击按钮时,进度条设置为选取框,然后调用我的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

In my code, when a button is clicked the progress bar is set to marquee and then my BackgroundWorker is called but when the BackgroundWorker is called the progress bar freezes or disappears. I use the BackgroundWorker to seperate the RefreshReport method of the ReportViewer from the UI 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最佳男配角 2024-07-17 18:11:30

问题是当您在 RefreshReport() 方法中调用 .BeginInvoke() 时。 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 中的可视控件不是线程安全的,因此永远不要直接执行任何需要花费几分钟才能完成的操作。 您在 RefreshReport() 方法中使用 .BeginInvoke() 进行的操作具有在主 UI 线程中调用长时间运行的函数的效果嗯>。

要解决此问题,您需要关闭跨线程检查,以便不引发异常(简单,但不推荐),或者更改使用控件的方式,以便主要工作发生在其他地方,并且控件仅在以下情况下引发事件:事情已经准备好了。 如果您无法将控件修改到那种程度,则说明控件存在设计缺陷。

The problem is when you call .BeginInvoke() in your RefreshReport() method. The BackgroundWorker.DoWork() method is already raised in a different 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 a Monitor to lock your report object and prevent re-entry.

Right now, when you call .BeginInvoke() the report process kicks off, but it doesn't block at all so there's nothing left for the DoWork() method to do. It just returns right away. At this point the BackgroundWorker thinks it's done, so calls the .RunWorkerCompleted() method, which stops your progress bar.


Based on the comment, rvReport is a visual control rather than a component or simple data access class. In that case, you should know that visual controls in .Net are not thread safe, and therefore should never directly do anything directly that takes more than a few moments to complete. The hoops you were jumping through with .BeginInvoke() in the RefreshReport() method had the effect of calling your long running function in the main UI thread.

To solve this problem, you need to either turn off cross thread checking so that the exception is not thrown (simple, but not recommended) or change how you use the control, so that the main work happens elsewhere and the control just raises events when things are ready. If you can't modify the control to that extent, it's a design flaw in the control.

小ぇ时光︴ 2024-07-17 18:11:30

问题在于,当背景标题有处理器时,进度条没有机会重新绘制。 因此,您需要在处理时从主等待线程调用 System.Windows.Forms.Application.DoEvents()。 这将获得控制并导致进度条重新绘制。

因此,在BackgroundWorker1.RunWorkerAsync 调用之后,您可以添加一个循环来调用DoEvents,直到引发事件,然后在RunWorkerCompleted 中引发事件以使调用代码退出。 由于这不允许主代码继续运行,您可以将调用放在后台调用或另一个线程中。

The problem is that the progress bar is not being given a chance to repaint while the background thead has the processor. So you need to call System.Windows.Forms.Application.DoEvents() from the main waiting thread while you are processing. This will get control and cause the progress bar to repaint.

So after the BackgroundWorker1.RunWorkerAsync call you can add a loop to call DoEvents until an event is raised and then raise the event in RunWorkerCompleted to let the calling code exit. Since this doesnt allow the main code to continue running you could put the call in the Background call or another thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文