2010-07-08 51 views
0

我使用Vb.net visual studio 2008.我有一個進程(system.diagnostics.process)在後臺運行,它更新了Ui線程進度條和一個標籤,我已經使用backgroundworker.runworkerAsync工作。現在的問題是我必須用不同的輸入工作多次。VB.Net一個循環內的異步後臺工作

的代碼塊:

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 

在這裏的問題是fnStartEvent方法一旦被啓動,它會調用BackgroundWorker1.runWorkerAsync進程,在一個單獨的線程中運行,並且不等待線程完成然後它移動到下一行代碼,即循環到下一個項目,並返回到相同的BackgroundWorker1.runWorkerAsync行,並引發它已在運行的異常。

試圖 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 

但這並不更新用來表示進度UI線程。

2.在DoWork線程中放入整個進程,併爲其中的每個文件循環,但要在進度條更新中返回交叉線程錯誤。

什麼是標準程序在爲後臺工程人員執行循環以等待完成以及更新UI而不會阻止它。

回答

0

每當你使用Thread.Sleep,你實際上正在睡眠當前掛鉤到你的啓動類(即表單)的線程。所以,如果你睡覺你的主線程,不會發生UI更新。

根據關於BackgroundWorker.IsBusy的MSDN文章,您需要拋出一個Application.DoEvents。下面的代碼從上面鏈接的文章複製而來。


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

感謝josaph,它的工作。但是有沒有其他的解決方案相同,bCoz有許多線程循環出現在這裏。 – Naresh 2010-07-08 14:07:12