Domanda

Nel mio codice, quando si fa clic su un pulsante, la barra di avanzamento viene impostata su perimetro, quindi viene chiamato il mio BackgroundWorker ma quando viene chiamato BackgroundWorker, la barra di avanzamento si blocca o scompare. Uso BackgroundWorker per separare il metodo RefreshReport di ReportViewer dal thread dell'interfaccia utente. Qualsiasi aiuto è apprezzato. Grazie!

    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
È stato utile?

Soluzione

Il problema è quando si chiama .BeginInvoke () nel metodo RefreshReport () . Il metodo BackgroundWorker.DoWork () è già stato generato in un thread diverso, quindi puoi semplicemente chiamare rvReport.RefreshReport () . Dovrebbe apparire così:

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

È davvero così semplice, con la possibile aggiunta dell'uso di un Monitor per bloccare l'oggetto del report e impedire il rientro.

In questo momento, quando chiami .BeginInvoke () il processo di report inizia, ma non si blocca affatto, quindi non rimane nulla per DoWork () metodo da fare. Ritorna subito. A questo punto BackgroundWorker pensa che sia fatto, quindi chiama il metodo .RunWorkerCompleted () , che arresta la barra di avanzamento.


Sulla base del commento, rvReport è un controllo visivo piuttosto che un componente o una semplice classe di accesso ai dati. In tal caso, dovresti sapere che i controlli visivi in ??.Net non sono thread-safe, e quindi non fare direttamente direttamente tutto ciò che richiede più di qualche istante per essere completato. I cerchi che hai passato con .BeginInvoke () nel metodo RefreshReport () hanno avuto l'effetto di chiamare la tua funzione long running nel thread dell'interfaccia utente principale .

Per risolvere questo problema, è necessario disattivare il controllo incrociato del thread in modo che l'eccezione non venga generata (semplice, ma non consigliata) o modificare il modo in cui si utilizza il controllo, in modo che il lavoro principale avvenga altrove e il controllo solo genera eventi quando le cose sono pronte. Se non puoi modificare il controllo in quella misura, è un difetto di progettazione nel controllo.

Altri suggerimenti

Il problema è che alla barra di avanzamento non viene data la possibilità di ridipingere mentre il thead in background ha il processore. Quindi è necessario chiamare System.Windows.Forms.Application.DoEvents () dal thread di attesa principale durante l'elaborazione. Ciò otterrà il controllo e ridipingerà la barra di avanzamento.

Quindi dopo la chiamata BackgroundWorker1.RunWorkerAsync puoi aggiungere un ciclo per chiamare DoEvents fino a quando non viene generato un evento e quindi sollevare l'evento in RunWorkerCompleted per consentire l'uscita del codice chiamante. Poiché ciò non consente al codice principale di continuare l'esecuzione, è possibile inserire la chiamata nella chiamata in background o in un altro thread.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top