Я использую Vb.net Visual Studio 2008. У меня есть процесс (system.diagnostics.process) для запуска в фоновом режиме, и он обновляет строку прогресса потока UI и метку, и я обработал его с помощью backgroundworker.runworkerAsync. Теперь проблема в том, что я должен работать один и тот же процесс некоторое время с разными входами.
Кодовый блок:
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
Но это не обновляет поток пользовательского интерфейса, используемый для обозначения прогресса.
2. Поместите весь процесс в поток DoWork и выполните цикл для каждого файла там, но это возвращает кросс-поточную ошибку при обновлении индикатора выполнения.
какова стандартная процедура выполнения цикла для фонового работника, ожидающего завершения, а также обновления пользовательского интерфейса без его блокировки.