0

Im utilisant Vb.net visual studio 2008. J'ai un processus (system.diagnostics.process) à exécuter en arrière-plan et il met à jour la barre de progression du thread Ui et une étiquette et je l'ai travaillé en utilisant backgroundworker.runworkerAsync. Maintenant, le problème est que je dois travailler le même processus pendant un certain temps avec différentes entrées.VB.Net Travailleur d'arrière-plan asynchrone à l'intérieur d'une boucle

Le bloc de code est:

Private Sub fnStartEvent(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.click 

Dim inputFolder = Directory.GetFiles(textboxSourceFolder.text) 
Dim currentNumberOfFile As Integer=1 
For each Files in inputFolder 
    Dim arguments As Object = Files 
    updateProgressStatus(0, currentNumberOfFile) 
    BackgroundWorker1.WorkerReportsProgress = True 
    BackgroundWorker1.RunWorkerAsync(New Object() {arguments}) 
    currentNumberOfFile += 1 
    Next  
End Sub 

    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork 
    'uses the arguments 
     Dim Bg_process As System.Diagnostics.Process = New System.Diagnostics.Process 
      With Bg_process.StartInfo 
       .Arguments = str_arguments 
       .FileName = ffmpegPath 
       .CreateNoWindow = True 
       .UseShellExecute = False 
       .RedirectStandardOutput = True 
       .RedirectStandardError = True 
      End With 

      Bg_process.Start() 
      Dim outputReader As StreamReader = Bg_process.StandardError 
      Dim output As String 

      While Not Bg_process.HasExited 
       output = outputReader.ReadLine() 
       BackgroundWorker1.ReportProgress(0, output) 
       Threading.Thread.Sleep(500) 
      End While 
     End Sub 

Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged 
    ' process args 

updateProgressStatus(args(0), args(1)) 
End Sub 

Private Function BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted 
      Messagebox.Show(e.error.ToString) 
End Try 

    Sub updateProgressStatus(ByVal progressValue As Integer, ByVal progressStatus As String) 
progressBar.value = progressValue 
lblprogressStatus.Text = progressStatus 
     End Sub 

Le problème ici est la méthode fnStartEvent se fois commencé, il appelle processus BackgroundWorker1.runWorkerAsync et qui fonctionne dans un fil séparé et ne pas attendre pour le fil à compléter et il passe à la ligne de code suivante ie les boucles à l'élément suivant et il retourne à la même ligne BackgroundWorker1.runWorkerAsync et jette l'exception qu'il est déjà en cours d'exécution.

Essayé 1.

Private Sub fnStartEvent(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.click 
    Dim inputFolder = Directory.GetFiles(textboxSourceFolder.text) 
    Dim currentNumberOfFile As Integer=1 
    For each Files in inputFolder 

     Dim arguments As Object = Files 
     updateProgressStatus(0, currentNumberOfFile) 
     BackgroundWorker1.WorkerReportsProgress = True 
     BackgroundWorker1.RunWorkerAsync(New Object() {arguments}) 
    '' 
     Do Until BackgroundWorker1.IsBusy 
     Thread.Sleep(500) 
     Loop 

    currentNumberOfFile += 1 
    Next  
End Sub 

Mais cela ne met à jour pas le fil Ui utilisé pour désigner les progrès.

2.Placez le processus entier à l'intérieur du thread et de la boucle DoWork pour chaque fichier lui-même, mais pour renvoyer l'erreur d'interconnexion dans la mise à jour de la barre de progression.

Quelle est la procédure standard d'exécution d'une boucle pour que l'arrière-plan attende la fin de la mise à jour ainsi que la mise à jour de l'interface utilisateur sans la bloquer.

Répondre

0

Chaque fois que vous utilisez Thread.Sleep, vous dormez réellement le thread en cours qui est accroché à votre classe de démarrage (par exemple, Form). Donc, si vous dormez votre thread principal, aucune mise à jour de l'interface utilisateur ne se produira.

Par l'article MSDN concernant BackgroundWorker.IsBusy, vous devez lancer un Application.DoEvents. Le code ci-dessous est copié de l'article lié ci-dessus.


Private Sub downloadButton_Click(_ 
    ByVal sender As Object, _ 
    ByVal e As EventArgs) _ 
    Handles downloadButton.Click 

    ' Start the download operation in the background. 
    Me.backgroundWorker1.RunWorkerAsync() 

    ' Disable the button for the duration of the download. 
    Me.downloadButton.Enabled = False 

    ' Once you have started the background thread you 
    ' can exit the handler and the application will 
    ' wait until the RunWorkerCompleted event is raised. 

    ' If you want to do something else in the main thread, 
    ' such as update a progress bar, you can do so in a loop 
    ' while checking IsBusy to see if the background task is 
    ' still running. 
    While Me.backgroundWorker1.IsBusy 
     progressBar1.Increment(1) 
     ' Keep UI messages moving, so the form remains 
     ' responsive during the asynchronous operation. 
     Application.DoEvents() 
    End While 
End Sub 
+0

merci josaph, son travail.Mais y at-il une autre solution pour le même, bCoz il existe de nombreuses boucles de fil surgissant ici. – Naresh

Questions connexes