Frage

In meinem Code, wenn eine Taste der Fortschrittsbalken angeklickt wird, auf Festzelt und dann wird mein Background genannt, aber wenn der Background wird der Fortschrittsbalken friert oder verschwindet genannt. Ich verwende den Background die Refresh Verfahren des Reports vom UI-Thread zu trennen. Jede Hilfe ist willkommen. Dank!

    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
War es hilfreich?

Lösung

Das Problem ist, wenn Sie .BeginInvoke() in Ihrem RefreshReport() Methode aufrufen. Die BackgroundWorker.DoWork() Methode wird bereits in einem anderen Thread angehoben, so können Sie einfach rvReport.RefreshReport() nennen. Es soll wie folgt aussehen:

Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    rvReport.RefreshReport()
End Sub

Es ist wirklich so einfach, mit der möglichen Zugabe einer Monitor der Verwendung Ihres Bericht Objekt zu sperren und den Wiedereintritt verhindern.

Im Moment, wenn Sie .BeginInvoke() der Bericht Prozess startet nennen, aber es blockiert nicht gar so gibt es nichts für die DoWork() Methode noch zu tun. Es gibt nur sofort. An diesem Punkt der Background es gemacht denkt, ruft so die .RunWorkerCompleted() Methode, die Ihre Fortschrittsbalken stoppt.


Auf der Grundlage des Kommentar, rvReport ist eine visuelle Kontrolle eher als eine Komponente oder einfache Datenzugriffsklasse. In diesem Fall sollten Sie wissen, dass visuelle Kontrollen in .Net sind nicht Thread-sicher, und deshalb sollte nie direkt etwas tun direkt, dass mehr braucht, als ein paar Minuten zu vervollständigen. Die Reifen Sie in der .BeginInvoke() Methode mit RefreshReport() springend durch waren, hatten den Effekt der langen Lauf Funktion im Haupt-UI-Thread aufrufen .

Um dieses Problem zu lösen, müssen Sie entweder Querfadenprüfung deaktivieren, so dass die Ausnahme nicht ausgelöst wird (einfach, aber nicht empfohlen) oder ändern, wie Sie das Steuerelement verwenden, so dass die Hauptarbeit an anderer Stelle und die Kontrolle passiert einfach Ereignisse auslöst, wenn die Dinge fertig sind. Wenn Sie nicht die Kontrolle in diesem Ausmaß ändern können, ist es ein Konstruktionsfehler in der Steuerung.

Andere Tipps

Das Problem ist, dass die Fortschrittsbalken werden keine Chance gegeben werden, neu zu zeichnen, während der Hintergrund Thead den Prozessor hat. Sie muß also System.Windows.Forms.Application.DoEvents () aus dem Hauptwartende Thread nennen, während Sie verarbeiten. Dies wird Kontrolle bekommen und bewirken, dass die Fortschrittsbalken neu zu streichen.

So, nachdem die BackgroundWorker1.RunWorkerAsync rufen Sie eine Schleife hinzufügen können DoEvents aufrufen, bis ein Ereignis ausgelöst wird und dann das Ereignis in RunWorkerCompleted erhöhen die Telefonvorwahl Ausfahrt zu lassen. Da diese nicht der Hauptcode ermöglichen, weiterhin laufen Sie den Anruf im Hintergrund Anruf oder einen anderen Thread setzen könnten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top