StandardOutput.ReadToEnd() 挂起 [英] StandardOutput.ReadToEnd() hangs

查看:27
本文介绍了StandardOutput.ReadToEnd() 挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个经常使用外部程序并读取其输出的程序.使用您通常的进程重定向输出,它可以很好地工作,但是当我尝试读取它时,由于某种原因一个特定参数挂起,没有错误消息 - 没有例外,它只是在到达该行时停止".我当然使用一个集中的函数来调用和读取程序的输出,就是这样:

I have a program that frequently uses an external program and reads its outputs. It works pretty well using your usual process redirect output, but one specific argument for some reason hangs when I try to read it, no error message - no exception, it just 'stops' when it reaches that line. I of course use a centralized function to call and read output from the program, which is this:

public string ADBShell(string adbInput)
{
    try
    {
        //Create Empty values
        string result = string.Empty;
        string error = string.Empty;
        string output = string.Empty;
        System.Diagnostics.ProcessStartInfo procStartInfo 
            = new System.Diagnostics.ProcessStartInfo(toolPath + "adb.exe");

        procStartInfo.Arguments = adbInput;
        procStartInfo.RedirectStandardOutput = true;
        procStartInfo.RedirectStandardError = true;
        procStartInfo.UseShellExecute = false;
        procStartInfo.CreateNoWindow = true;
        procStartInfo.WorkingDirectory = toolPath;
        System.Diagnostics.Process proc = new System.Diagnostics.Process();
        proc.StartInfo = procStartInfo;
        proc.Start();
        // Get the output into a string
        proc.WaitForExit();
        result = proc.StandardOutput.ReadToEnd();
        error = proc.StandardError.ReadToEnd();  //Some ADB outputs use this
        if (result.Length > 1)
        {
            output += result;
        }
        if (error.Length > 1)
        {
            output += error;
        }
        Return output;
    }
    catch (Exception objException)
    {
        throw objException;
    }
}

挂起的那一行是 result = proc.StandardOutput.ReadToEnd();,但同样,不是每次,只有在发送特定参数(start-server")时.所有其他参数都可以正常工作 - 它读取值并返回它.它的悬挂方式也很奇怪.它不会冻结或给出错误或任何东西,它只是停止处理.就好像它是一个返回"命令,除了它甚至不返回调用函数之外,它只是在界面仍然启动并运行的情况下停止一切.有没有人经历过这种情况?任何人都知道我应该尝试什么?我假设它在流本身中是出乎意料的,但是有没有办法可以处理/忽略它,以便它无论如何都会读取它?

The line that hangs is result = proc.StandardOutput.ReadToEnd();, but again, not every time, only when sent a specific argument ("start-server"). All other arguments work just fine - it reads the value and returns it. It's also strange the way it hangs. It doesn't freeze or give an error or anything, it just stops processing. As if it was a 'return' command, except it doesn't even return to the calling function, it just stops everything with the interface still up and running. Anyone experienced this before? Anyone have any idea what I should try? I'm assuming it's something unexpected within the stream itself, but is there a way I can handle/ignore this so that it reads it anyway?

推荐答案

Proposed solutions with BeginOutputReadLine() 是一个好方法,但在这种情况下,它不适用,因为过程(当然使用 WaitForExit()) 在异步输出完全完成之前退出.

Proposed solutions with BeginOutputReadLine() are a good way but in situations such as that, it is not applicable, because process (certainly with using WaitForExit()) exits earlier than async output finished completely.

所以,我尝试同步实现它,发现解决方案是使用 StreamReader 类中的 Peek() 方法.我添加了检查 Peek() >-1 确保它不是 MSDN 文章 进行了描述,终于可以正常工作并停止挂起!

So, I tried to implement it synchronously and found that the solution is in using Peek() method from StreamReader class. I added check for Peek() > -1 to sure that it is not the end of the stream as in MSDN article described and finally it works and stop hanging!

代码如下:

var process = new Process();
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.WorkingDirectory = @"C:	est";
process.StartInfo.FileName = "test.exe";
process.StartInfo.Arguments = "your arguments here";

process.Start();
var output = new List<string>();

while (process.StandardOutput.Peek() > -1)
{
    output.Add(process.StandardOutput.ReadLine());
}

while (process.StandardError.Peek() > -1)
{
    output.Add(process.StandardError.ReadLine());
}
process.WaitForExit();

这篇关于StandardOutput.ReadToEnd() 挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆