选取框ProgressBar与BackgroundWorker无响应 [英] Marquee ProgressBar unresponsive with BackgroundWorker

查看:113
本文介绍了选取框ProgressBar与BackgroundWorker无响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的代码中,当单击按钮时,进度条设置为选取框,然后调用我的BackgroundWorker,但是当调用BackgroundWorker时,进度条冻结或消失.我使用BackgroundWorker将ReportViewer的RefreshReport方法与UI线程分开.任何帮助表示赞赏.谢谢!

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

推荐答案

问题是当您在RefreshReport()方法中调用.BeginInvoke()时. BackgroundWorker.DoWork()方法已经在其他线程中引发,因此您可以调用rvReport.RefreshReport().它应该看起来像这样:

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

这真的很简单,可以添加使用Monitor来锁定报表对象并防止再次输入.

It really is that simple, with the possible addition of using a Monitor to lock your report object and prevent re-entry.

现在,当您调用.BeginInvoke()时,报告过程开始了,但是它根本没有阻塞,因此DoWork()方法没有任何余地要做.它会立即返回.此时,BackgroundWorker认为已完成,因此调用.RunWorkerCompleted()方法,该方法将停止进度栏.

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.

基于注释,rvReport是可视控件,而不是组件或简单数据访问类.在这种情况下,您应该知道.Net中的可视控件不是线程安全的,因此,绝对不要直接直接执行任何需要花费一些时间才能完成的操作.在RefreshReport()方法中使用.BeginInvoke()跳转的循环效果是在主UI线程中调用了长期运行的函数.

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.

这篇关于选取框ProgressBar与BackgroundWorker无响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆