2

StreamReader を使用してプロセスから出力データを読み取ろうとしていますが、StreamReader がブロックされ、出力が返されません。

私のプロセスは次のようになります。

ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Arguments = args;
startInfo.FileName = filename;
StartInfo.WorkingDirectory = aDirectory;
StartInfo.UseShellExecute = false;
StartInfo.RedirectStandardOutput = true;
Process p = new Process();
p.StartInfo = startInfo;
p.Start();

StreamReader はその後すぐに呼び出されます。

StreamReader strmRead = p.StandardOutput;
char[] output = new char[4096];
while(true){
   strmRead.Read(output,0,output.Length);
   string outputString = new string(output);
   Debug.WriteLine(outputString);
}

コードは、Read メソッドの呼び出しでハングします。プログラムを手動で強制終了すると、プロセスからの出力がデバッグ コンソールに書き込まれます。プロセス出力は改行文字を使用しないため、Process.OutputDataReceived を使用しても機能しません。無期限にブロックすることなく、ストリームからプロセス出力を取得するにはどうすればよいですか?

編集:私がすでに得た答えを考えると、コードに問題があるのではなく、プロセスが標準出力を放棄したり、出力をフラッシュしたりしないという問題のようです。他の誰かが洞察を持っている場合は、お気軽にコメントしてください。

4

3 に答える 3

1

あなたはただすることができます:

String outputString = strmRead.ReadToEnd();
于 2012-05-31T18:32:01.893 に答える
1

4096 バイトを読み取っていますが、それより少ない可能性があるため、ストリーム ブロックを実行します。

また、ストリームからテキストを読み取るより効率的な方法もあります。 TextReaderメソッドがReadLineある場合は、代わりにそれを試してください。

http://msdn.microsoft.com/en-us/library/system.io.textreader.readline.aspx

ところで、while (true)??? どのように終了する予定ですか?

于 2012-05-31T18:28:46.027 に答える
1

この質問はかなり古いことを知っています。しかし、私は同様の問題を抱えていました。Peek() メソッドを使用してみましたが、Peek() が -1 を返したとしても、必ずしもストリームの終わりではありませんでした。

Peek() が -1 を返したときに次の文字を読み取ろうとする新しいスレッドを開始することで、問題を解決しました。

                    string toRead = "";
                    do
                    {
                        if (reader.Peek() == -1)
                        {
                            Thread td = new Thread(TryReading);
                            td.Start();
                            Thread.Sleep(400);
                            if (ReadSuccess == false)
                            {
                                try
                                {
                                    td.Abort();
                                }
                                catch (Exception ex) { }
                                break;
                            }
                            else
                            {
                                toRead += ReadChar;
                                ReadSuccess = false;
                            } 
                        }
                        toRead += (char)reader.Read();
                    } while (true);

TryReading() メソッドは次のように定義されています。

static char ReadChar = 'a';
static bool ReadSuccess = false;

static void TryReading(object callback)
{
    int read = reader.Read();
    ReadChar = (char)read;
    ReadSuccess = true;
}

基本的に...スレッドが文字を読み取るのに時間がかかりすぎた場合-スレッドを中止し、これまでに読み取ったテキストを使用しました。

これで問題は解決しました。

于 2014-07-27T09:50:53.883 に答える