Yorkshireman2
Programmer
There are many similar problems on the internet but none have solved this exact problem.
I use a process and delegate to call a c program and redirect output to a textbox.
I want the textbox to update line by line, in real time. BUT it seems to wait until a large chunk of text is in the textbox.text property before repainting it.
Note 1: I found none of the delegate calls run until the main sub cmdReadFields_Click() finishes and exits;
THEN all the calls to the delegate are executed and the text box prints out all the text at the end.
Interesting- I thought a separate thread would be running these delegate events while the GUI command button event is still running.
Note 2: I tried a breakpoint in the UpdateTextBox() sub and I watched the value of txtOutput.text.
The text property was actually updating at each call but the GUI textbox did NOT update/refresh until it was 'nearly all done'.
When the c program runs in a console it prints to screen a line-by-line report of what the code is doing as it creates a copy of a dll,
creates an object in memory and reads data fields from that object then destroys the object and dll copy.
( The c program prints a line feed after each line and flushes the buffer )
HOWEVER, WHEN the c program runs in the vb.net thread (process), the textbox shows nothing while the console program is gradually printing out the
creation messages, reading data values etc. then the textbox suddenly updates to show the entire block of text lines; Then it again pauses while the
c program is destroying the objects and printing out strings about this; THEN the textbox suddenly prints those lines out.
Note 3: I tried application.doEvents, as many internet posts suggest, but that does not refresh the textbox in real time either.
In fact... when I put a breakpoint in the UpdateTextBox() sub and let it run one call at a time, the GUI actually DID update the textbox at each line BUT when I
run the code without the breakpoint, the textbox does NOT update for each line.
I can only assume the successful update when stepping through the code is because the IDE is passing focus between the GUI and code as I step through,
whereas in continuous run mode the textbox never receives a paint message.(?)
Note 4: I also tried using an exit event for the process at one time and I had tried commenting out the mProcess.close and mProcess.dispose statements
inside the main sub in case I was somehow destroying the process before my exit event was called but that did not help anything.
***** SO.. Has anyone already solved this?
How do I get the textbox to actually repaint at each update of the .text property so my lines are printed out one at a time, in real time, as the c program is doing behind the scenes???
I use a process and delegate to call a c program and redirect output to a textbox.
I want the textbox to update line by line, in real time. BUT it seems to wait until a large chunk of text is in the textbox.text property before repainting it.
Code:
Private Sub cmdReadFields_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdReadFields.Click
txtOutput.AppendText(vbCrLf & "Reading Fields from " & gstrSimulatorType & vbCrLf)
mProcess = New Process
AddHandler mProcess.OutputDataReceived, AddressOf process_OutputDataReceived
AddHandler mProcess.ErrorDataReceived, AddressOf process_OutputDataReceived
' handlers should send both output and errors to same handling sub
' now can call the c program in a process (separate thread) and redirect the output to the textbox
Dim startInfo As New ProcessStartInfo
startInfo.FileName = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory(), "ReadFields\ReadFieldsInfo.exe")
startInfo.WorkingDirectory = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory(), "ReadFields")
startInfo.UseShellExecute = False
startInfo.CreateNoWindow = True
'startInfo.RedirectStandardInput = True 'doesn't seem to help, so commented out
startInfo.RedirectStandardOutput = True
startInfo.RedirectStandardError = True
startInfo.ErrorDialog = True
mProcess.StartInfo = startInfo
mProcess.EnableRaisingEvents = True
Try
mProcess.Start()
mProcess.BeginOutputReadLine()
mProcess.BeginErrorReadLine()
Catch ex As Exception
MsgBox("error" & ex.Message)
Finally
mProcess.Close() ' tried commenting this out - no change
mProcess.Dispose() ' tried commenting this out - no change
End Try
End Sub
' fires from handler, when output data rcvd from process
Public Sub process_OutputDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
' called as the handler for data output being detected in the redirect
UpdateTextBox(e.Data)
End Sub
Delegate Sub UpdateTxtBoxDelegate(ByVal Text As String)
Public Sub UpdateTextBox(ByVal Tex As String)
If txtOutput.InvokeRequired Then
Dim myDelegate As New UpdateTxtBoxDelegate(AddressOf UpdateTextBox)
Dim args As Object() = {Tex}
Me.txtOutput.Invoke(myDelegate, args)
Else
txtOutput.AppendText(Tex & Environment.NewLine)
' application.doEvents ' tried this but only refreshes GUI when stepping through code with F11
End If
End Sub
Note 1: I found none of the delegate calls run until the main sub cmdReadFields_Click() finishes and exits;
THEN all the calls to the delegate are executed and the text box prints out all the text at the end.
Interesting- I thought a separate thread would be running these delegate events while the GUI command button event is still running.
Note 2: I tried a breakpoint in the UpdateTextBox() sub and I watched the value of txtOutput.text.
The text property was actually updating at each call but the GUI textbox did NOT update/refresh until it was 'nearly all done'.
When the c program runs in a console it prints to screen a line-by-line report of what the code is doing as it creates a copy of a dll,
creates an object in memory and reads data fields from that object then destroys the object and dll copy.
( The c program prints a line feed after each line and flushes the buffer )
HOWEVER, WHEN the c program runs in the vb.net thread (process), the textbox shows nothing while the console program is gradually printing out the
creation messages, reading data values etc. then the textbox suddenly updates to show the entire block of text lines; Then it again pauses while the
c program is destroying the objects and printing out strings about this; THEN the textbox suddenly prints those lines out.
Note 3: I tried application.doEvents, as many internet posts suggest, but that does not refresh the textbox in real time either.
In fact... when I put a breakpoint in the UpdateTextBox() sub and let it run one call at a time, the GUI actually DID update the textbox at each line BUT when I
run the code without the breakpoint, the textbox does NOT update for each line.
I can only assume the successful update when stepping through the code is because the IDE is passing focus between the GUI and code as I step through,
whereas in continuous run mode the textbox never receives a paint message.(?)
Note 4: I also tried using an exit event for the process at one time and I had tried commenting out the mProcess.close and mProcess.dispose statements
inside the main sub in case I was somehow destroying the process before my exit event was called but that did not help anything.
***** SO.. Has anyone already solved this?
How do I get the textbox to actually repaint at each update of the .text property so my lines are printed out one at a time, in real time, as the c program is doing behind the scenes???