StandardOutput流在进程退出后保持打开状态

时间:2017-06-04 20:00:52

标签: c# .net process adb

在使用.NET中的进程时,我已经习惯了退出进程将结束StandardOutput和StandardError的输出的行为。但是,我找到了一个似乎不是这样的exe,并且我想知道我的假设是否错误以及为什么错误

以下是重现我所看到的问题的代码。它使用特定版本的Android Debug Bridge可执行文件(可从https://hostr.co/bBxxj7gFfMlW获得)。

// before running, terminate any adb.exe processes on the system
// adb.exe's initial run leaves behind a background daemon that changes the
// behavior of future adb.exe runs

var process = new Process
{
    StartInfo =
    {
        FileName = @"C:\Users\[my user]\Downloads\ADB-1.0.31.zip\adb.exe",
        Arguments = "connect 127.0.0.1",
        CreateNoWindow = true,
        RedirectStandardError = true,
        RedirectStandardInput = false,
        RedirectStandardOutput = true,
        UseShellExecute = false,
    }
};
process.Start();

var tasks = new Task[] 
{
    Task.Run(() => { process.WaitForExit(); Console.WriteLine("Process exited"); }),
    Task.Run(() =>
    {
        int b;
        while ((b = process.StandardOutput.BaseStream.ReadByte()) != -1)
        {
            Console.WriteLine($"STDOUT: {b} ({(char)b})");
        }
        Console.WriteLine("STDOUT: DONE");
    }),
    Task.Run(() =>
    {
        int b;
        while ((b = process.StandardError.BaseStream.ReadByte()) != -1)
        {
            Console.WriteLine($"STDERR: {b} ({(char)b})");
        }
        Console.WriteLine("STDERR: DONE");
    })
};

Task.WaitAll(tasks);

我希望看到该进程运行一段时间,产生一些输出(逐字节地记录到控制台),然后退出。一旦进程退出,从流中读取的任务应该返回-1并退出。

所有这一切都发生了,除了在进程退出后,流保持打开状态,读者任务无限期地挂起在ReadByte()上。

修改

进一步挖掘并在Process的实现中发现了一些代码,强调了我希望流程在流程终止时关闭的期望。在WaitForExit()中,如果使用BeginOutputDataReadLine()异步传输输出,则等待调用将阻止确保异步输出读取器收到EOF(code)。如果上面的示例被修改为使用:

process.OutputDataReceived += (o, e) => Console.WriteLine(e.Data); process.BeginOutputReadLine();

而不是具有从StandardOutput读取字节的显式任务,而WaitForExit()任务永远不会返回(尽管轮询process.HasExited在一段时间后返回false)!

0 个答案:

没有答案