Reputation: 137
I'm trying to retrieve the output lines generated by a process I started, here's the code
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
foreach (myData singleJob in e.Argument as List<myData>)
{
ProcessStartInfo psi = new ProcessStartInfo("myCommandLineProgram.exe");
psi.Arguments = "\"" + singleJob.row + "\"";
psi.CreateNoWindow = true;
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.UseShellExecute = false;
Process p = new Process();
p.StartInfo = psi;
p.Start();
StreamReader sr = p.StandardOutput ;
string line;
while ((line = sr.ReadLine()) != null )
{
this.Invoke((MethodInvoker)delegate
{
richTextBox1.AppendText(sr.ReadLine() + Environment.NewLine);
richTextBox1.ScrollToCaret();
});
}
//StreamReader streamOutput = p.StandardOutput;
//string content = streamOutput.ReadToEnd();
//this.Invoke((MethodInvoker)delegate
//{
// richTextBox1.AppendText(content + Environment.NewLine);
//});
p.WaitForExit();
}
}
While the commented out code is always working (but it doesn't parse line by line), the code above is somehow faulty, indeed some lines fail to appear into the richtextbox and some others are blank.
Thanks
Upvotes: 1
Views: 145
Reputation: 29164
Shouldn't that be something like
richTextBox1.AppendText(line + Environment.NewLine);
(line
instead of sr.ReadLine()
)?
Calling readLine()
twice will discard every second line.
Also, since you're calling ReadLine
in the delegate you cannot control when the read occurs. It might be that there were several ReadLines()
(from the while
line) in between.
Note, that you should also NOT use the line
variable: This variable always references the same line variable in the loop, this one might contain new content at the time the AppendText
is executed. You should introduce a new local variable inside the loop like
while ((line = sr.ReadLine()) != null )
{
var theLine = line;
this.Invoke((MethodInvoker)delegate
{
richTextBox1.AppendText(theLine + Environment.NewLine);
richTextBox1.ScrollToCaret();
});
}
Upvotes: 3
Reputation: 8656
Just change here instead of ReadLine()
, put line
. You have already read the line in your while loop
string appendingLine = line;
this.Invoke((MethodInvoker)delegate
{
richTextBox1.AppendText(appendingLine + Environment.NewLine);
richTextBox1.ScrollToCaret();
});
EDIT: The answer MartinStettner gave is better one. There may be the case where line
changes before the delegate is executed, therefore some lines can be lost while others can be repeated. Therefore I will change my answer according to Martin's and I want to point out that he should be the one who will take the credit for this answer.
Upvotes: 2