0

In the code below, taken from this solution, parallel processes can be launched and stdout is read one line at a time and the output stored in the form's controls. It works like a charm.

Private Function Test_ParallelTasks(ByVal MediaToConvert As String, OutCtl As TextBox) As Integer
    Dim _processexitcode As Integer
    Dim _CurrentProcessInfo As Integer
    Dim _CurrentProcess As Integer

    Task.Factory.StartNew(Function()
        psInfoPool.Add(New ProcessStartInfo)
        _CurrentProcessInfo = psInfoPool.Count - 1
        psInfoPool(_CurrentProcessInfo).RedirectStandardOutput = True
        psInfoPool(_CurrentProcessInfo).CreateNoWindow = True
        psInfoPool(_CurrentProcessInfo).UseShellExecute = False
        psInfoPool(_CurrentProcessInfo).FileName = "Tracert"  'psInfo.FileName = ".\mycmd.exe"
        psInfoPool(_CurrentProcessInfo).Arguments = MediaToConvert
        psInfoPool(_CurrentProcessInfo).WindowStyle = ProcessWindowStyle.Hidden

        ProcessPool.Add(New Process)
        _CurrentProcess = ProcessPool.Count - 1
        ProcessPool(_CurrentProcess) = New Process() With {.StartInfo = psInfoPool(_CurrentProcessInfo),
                                                           .EnableRaisingEvents = True,
                                                           .SynchronizingObject = Me}

        ProcessPool(_CurrentProcess).Start()
        ProcessPool(_CurrentProcess).BeginOutputReadLine()

        AddHandler ProcessPool(_CurrentProcess).OutputDataReceived,
            Sub(sender As Object, e As DataReceivedEventArgs)
                If e.Data IsNot Nothing Then
                    Try
                        'Update the UI or report progress 
                        Dim UpdateUI As Task = Task.Factory.StartNew(Sub()
                        Try
                            OutCtl.AppendText(e.Data + Environment.NewLine)
                        Catch exp As Exception
                              'An exception may raise if the form is closed
                        End Try

                        End Sub, CancellationToken.None, TaskCreationOptions.PreferFairness, _Scheduler)
                        UpdateUI.Wait()

                    Catch exp As Exception
                       'Do something here
                    End Try
                End If
            End Sub

        'Add an event handler for the Exited event
        AddHandler ProcessPool(_CurrentProcess).Exited,
                Sub(source As Object, ev As EventArgs)
                    _processexitcode = ProcessPool(_CurrentProcess).ExitCode
                    Console.WriteLine("The process has exited. Code: {0}  Time: {1}",
                    _processexitcode,
                    ProcessPool(_CurrentProcess).ExitTime)
                End Sub

        ProcessPool(_CurrentProcess).WaitForExit()
        ProcessPool(_CurrentProcess).Close()
        Return _processexitcode
    End Function, TaskCreationOptions.LongRunning, CancellationToken.None)

    Return If(_processexitcode = 0, 1, 0)
End Function

The problem is my background application only uses a CR while its processing to show the percentage completed. So you see: 1% 2% etc with the previous value being overwritten after each update.

When I plug in my exe in the code above, no text is returned during processing, ie handler doesn't fire. When processing is complete and the application ends the output I get is the final result. How can I read stdout so that I can show the progress to the UI using the task factory solution above (or something comparable)? I am using .net 4.8

Dude named Ben
  • 507
  • 3
  • 16
  • The Process class is designed to detect CR or LF or CR+LF. CR is the most relevant char, LF is skipped when present -- Specify what .NET version you're targeting and describe what the underlying process is actually doing -- That code doesn't exactly represent a good example of this procedure. I'll probably rewrite it using current standards – Jimi Apr 18 '23 at 13:27
  • @Jimi Edited question to clarify. – Dude named Ben Apr 18 '23 at 16:05
  • @jimi Found the problem. Progress was output to stderr for some strange reason, hence the reason I didn't see anything. Updated code to include handler for that and it works as expected now. I'll delete the question shortly. – Dude named Ben Apr 18 '23 at 16:24
  • That's the reason why I asked whether you could show the Console code -- I'll notify you if/when I update that code (probably will, I don't like it) – Jimi Apr 18 '23 at 16:48

0 Answers0