2012-05-31 5 views
2

Я пытаюсь использовать StreamReader для чтения выходных данных из процесса, но StreamReader блокирует и не возвращает какой-либо из результатов.Streamreader.Read blocks/RedirectStandardOutput used

Мой процесс выглядит следующим образом:

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

Код висит на вызов метода чтения. Когда я вручную убиваю программу, вывод из процесса записывается в консоль отладки. Выход процесса не использует символы новой строки, поэтому использование Process.OutputDataReceived не работает. Как я могу получить выход процесса из потока, не блокируя его бесконечно?

Редактировать: Учитывая ответы, я уже понял, что проблема связана с тем, что процесс не отказывается от стандартного вывода или не выполняет промывку, а не что-то не так с моим кодом. Если кто-либо еще имеет какое-либо понимание, не стесняйтесь комментировать.

+0

Я отредактировал заголовок вашего вопроса, чтобы он лучше предложил вашу проблему, возможно, вы получите более полезные ответы таким образом. –

ответ

1

Вы читаете 4096 байт, а их может быть меньше, поэтому блоки потоков.

Кроме того, есть более эффективные способы чтения текста из потоков. TextReader есть ReadLine способ, попробуйте, вместо этого.

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

BTV, while (true) ??? Как вы планируете выйти?

+0

+1 У StreamReader также есть ReadLine и ReadToEnd, которые могут быть полезны. – kenny

+1

На выходе нет символов новой строки, поэтому ReadLine также блокирует. – Justin

+0

Также программа по-прежнему блокирует, если я изменяю количество байтов до 4 вместо 4096. – Justin

1

Вы только могли бы сделать:

String outputString = strmRead.ReadToEnd(); 
+0

То же самое происходит с ReadToEnd вместо Read. – Justin

+1

Посмотрите на [это] (http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput.aspx). В нем говорится о тупиковых условиях, когда пара абзацев опущена. – DLH

+0

Итак, вы говорите, что процесс никогда не отказывается от стандартного для StreamReader, чтобы читать из него? – Justin

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

В принципе ... если поток занимает слишком много времени, чтобы прочитать характер - я прерван его и использовала текст прочитанные до сих пор.

Это исправило проблему для меня.

Смежные вопросы