Streamreader.Read blocks / RedirectStandardOutput used
本文关键字:RedirectStandardOutput used blocks Read Streamreader | 更新日期: 2023-09-27 18:36:00
我正在尝试使用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 不起作用。如何在不无限期阻塞的情况下从流中获取进程输出?
编辑:鉴于我已经得到的答案,该过程似乎是一个问题,没有放弃标准或不刷新输出,而不是我的代码有什么问题。如果其他人有任何见解,请随时发表评论。
您正在读取 4096 个字节,并且可能更少,因此流块。
此外,还有更有效的方法来从流中读取文本。 TextReader
有ReadLine
方法,请尝试一下。
http://msdn.microsoft.com/en-us/library/system.io.textreader.readline.aspx
顺便说一句,while (true)
??? 你打算如何退出?
你可以
这样做:
String outputString = strmRead.ReadToEnd();
我知道这个问题已经很老了。但我也有类似的问题。我尝试使用 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;
}
基本上。。。如果线程读取字符的时间太长 - 我中止了它并使用了到目前为止阅读的文本。
这为我解决了问题。