1

開始したプロセスによって生成された出力行を取得しようとしています。コードは次のとおりです

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();
    }
}

コメント アウトされたコードは常に機能しますが (ただし、行ごとに解析されません)、上記のコードには何らかの問題があります。実際、リッチテキスト ボックスに表示されない行や空白の行があります。

ありがとう

4

2 に答える 2

3

それは次のようなものではないでしょうか

richTextBox1.AppendText(line + Environment.NewLine);

(line代わりにsr.ReadLine())?

2 回呼び出すreadLine()と、2 行ごとに破棄されます。

また、デリゲートを呼び出しReadLineているため、読み取りがいつ発生するかを制御することはできません。ReadLines()その間に(行から)いくつかあった可能性がありますwhile

変数も使用しないでくださいline。この変数は常にループ内の同じ行変数を参照します。この変数には、実行時に新しいコンテンツが含まれている可能性がありますAppendText。次のように、ループ内に新しいローカル変数を導入する必要があります

 while ((line = sr.ReadLine()) != null )
 {
   var theLine = line;
   this.Invoke((MethodInvoker)delegate
   {
       richTextBox1.AppendText(theLine + Environment.NewLine);
       richTextBox1.ScrollToCaret();   
   });
 }
于 2012-10-21T21:48:58.563 に答える
2

の代わりにここを変更するだけReadLine()ですline。while ループの行を既に読んでいる

string appendingLine = line;
this.Invoke((MethodInvoker)delegate
{
          richTextBox1.AppendText(appendingLine + Environment.NewLine);
          richTextBox1.ScrollToCaret();   

});

編集: MartinStettner が与えた答えは、より良いものです。lineデリゲートが実行される前に変更が行われる場合があるため、一部の行が失われ、他の行が繰り返される可能性があります。したがって、私はMartin'sに従って私の答えを変更し、彼がこの答えの功績を認めるべきであることを指摘したいと思います.

于 2012-10-21T21:46:47.963 に答える