我正在尝试检索由我启动的进程生成的输出行,这是代码
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();
}
}
虽然注释掉的代码总是有效(但它不会逐行解析),但上面的代码有点错误,实际上有些行无法显示在richtextbox中,而其他一些行则是空白的。
由于
答案 0 :(得分:3)
不应该像
那样richTextBox1.AppendText(line + Environment.NewLine);
(line
代替sr.ReadLine()
)?
两次调用readLine()
将丢弃每一行。
此外,由于您在委托中调用ReadLine
,因此无法控制何时进行读取。可能是中间有几个ReadLines()
(来自while
行)。
注意,您也不应该使用line
变量:此变量始终引用循环中的相同行变量,此变量可能在AppendText
执行时包含新内容。你应该在循环中引入一个新的局部变量,如
while ((line = sr.ReadLine()) != null )
{
var theLine = line;
this.Invoke((MethodInvoker)delegate
{
richTextBox1.AppendText(theLine + Environment.NewLine);
richTextBox1.ScrollToCaret();
});
}
答案 1 :(得分:2)
只需更改此处而非ReadLine()
,将line
置于此处。您已经阅读了while循环中的行
string appendingLine = line;
this.Invoke((MethodInvoker)delegate
{
richTextBox1.AppendText(appendingLine + Environment.NewLine);
richTextBox1.ScrollToCaret();
});
编辑: MartinStettner给出的答案更好。可能存在line
在执行委托之前发生更改的情况,因此某些行可能会丢失而其他行可能会重复。因此,我会根据马丁的说法改变我的答案,并且我想指出他应该成为那个将这个答案归于此的人。