C# 输入数据不足时,标准数据管道不刷新?

C# 输入数据不足时,标准数据管道不刷新?,c#,linux,.net-core,C#,Linux,.net Core,我正在编写一个程序,该程序启动一个进程,然后写入进程的stdIn并从同一进程的stdOut读取 我的问题是,如果我没有大的数据集要写入stdIn,例如1字节,我就无法从stdOut获取数据,因为stdOut的ReadAsync函数永远不会返回 操作系统:Ubuntu 18.04 框架:dotnetcore2.2 语言:C# 下面是我用来编写stdIn的代码: public static async Task WriteToStdInAsync( Stream input,

我正在编写一个程序,该程序启动一个进程,然后写入进程的stdIn并从同一进程的stdOut读取

我的问题是,如果我没有大的数据集要写入stdIn,例如1字节,我就无法从stdOut获取数据,因为stdOut的
ReadAsync
函数永远不会返回

操作系统:Ubuntu 18.04 框架:dotnetcore2.2 语言:C#

下面是我用来编写stdIn的代码:

    public static async Task WriteToStdInAsync(
        Stream input,
        Stream stdIn
        )
    {
        await Task.Yield();
        byte[] buffer = new byte[1024 * 64];
        int read;
        while ((read = await input.ReadAsync(buffer, 0, buffer.Length)) > 0)
        {
            await stdIn.WriteAsync(buffer, 0, read);
        }
        await stdIn.FlushAsync();
    }
我从大小为1字节的“输入”流中读取数据,然后将数据传递给stdIn流

然后我试着用这种方式把那个字节取回来:

    public static async Task ReadFromStdOutAsync(
        Stream output,
        Stream stdOut
        )
    {
        await Task.Yield();
        byte[] buffer = new byte[1024 * 64];
        int read;
        while ((read = await stdOut.ReadAsync(buffer, 0, buffer.Length)) != 0)
        {
            await output.WriteAsync(buffer, 0, read);
        }
    }
        p.StandardInput.BaseStream,
        p.StandardOutput.BaseStream, 
等待stdOut.ReadAsync(buffer,0,buffer.Length)
-在这种情况下永远不会返回

如果我将输入流的大小增加到100KB(较小的值不起作用),则效果很好。如果我在将所有数据发送到stdIn后关闭stdIn流,它也适用于较小的大小。正如您所看到的,我试图刷新stdIn以强制数据传输,但它不起作用。我假设操作系统中有额外的缓冲级别,不允许stdOut查看数据

以下是我创建流程的方式:

        return new Process() {
            EnableRaisingEvents = false,                    
            StartInfo = new ProcessStartInfo {
                FileName = "python3",
                Arguments = $"{Settings.PipesEchoServer}",                    
                RedirectStandardOutput = true,
                RedirectStandardInput = true,
                UseShellExecute = false
            },
        };
我试图检查FileStream、Stream、Process的源代码,但找不到答案

谢谢你的帮助

编辑:

我是这样得到的:

    public static async Task ReadFromStdOutAsync(
        Stream output,
        Stream stdOut
        )
    {
        await Task.Yield();
        byte[] buffer = new byte[1024 * 64];
        int read;
        while ((read = await stdOut.ReadAsync(buffer, 0, buffer.Length)) != 0)
        {
            await output.WriteAsync(buffer, 0, read);
        }
    }
        p.StandardInput.BaseStream,
        p.StandardOutput.BaseStream, 
其中,
p
过程
类的一个实例

编辑2: 我想我发现了问题所在。我使用python脚本:

导入系统 read=sys.stdin.buffer.read(1024) 而len(read)!=0: sys.stdout.buffer.write(read) sys.stdout.buffer.flush() read=sys.stdin.buffer.read(1024*100) 但是看起来,sys.stdin.buffer.read在stdin的所有1024字节都变为红色之前不会返回结果。我将它改为
sys.stdin.buffer.read(1)
,现在它可以工作了

顺便说一句,我不确定这是在python中使用管道的最佳方式,但这是我发现的传输二进制数据的最简单方式


感谢GottZ提供的有关
setvbuf

的信息,c
setvbuf中有一个设置io缓冲类型的函数(stdout,NULL,_IOLBF,0)
如果你能在c#中使用它,你可能想检查一下。该行将标准输出设置为行缓冲。也许可以更仔细地看看您使用
setvbuf
的选项,我调用了一个python脚本,它使用
sys.stdout.buffer
将数据重定向到stdout。我使用它,因为我还没有找到更好的方法将二进制数据从stdin传输到stdout。我将从
sys.stdin.buffer.read(1024*100)
读取缓冲区的方式更改为
sys.stdin.buffer.read(1)
,这很有帮助。看起来,
sys.stdin.buffer.read
在获得所有字节数之前不会返回值。这是一个缓冲管道。总是。很高兴看到你找到了解决办法。如果你想有一个自定义的协议,你可以添加一个小的报头,它会告诉你下一个readhaving报头会带来多少数据,这是一个好主意,当我从这个POC移动到真正的程序时,我会记住它。非常感谢:)在c
setvbuf中有一个设置io缓冲类型的函数(stdout,NULL,_IOLBF,0)
如果你能在c#中使用它,你可能想检查一下。该行将标准输出设置为行缓冲。也许可以更仔细地看看您使用
setvbuf
的选项,我调用了一个python脚本,它使用
sys.stdout.buffer
将数据重定向到stdout。我使用它,因为我还没有找到更好的方法将二进制数据从stdin传输到stdout。我将从
sys.stdin.buffer.read(1024*100)
读取缓冲区的方式更改为
sys.stdin.buffer.read(1)
,这很有帮助。看起来,
sys.stdin.buffer.read
在获得所有字节数之前不会返回值。这是一个缓冲管道。总是。很高兴看到你找到了解决办法。如果你想有一个自定义的协议,你可以添加一个小的报头,它会告诉你下一个readhaving报头会带来多少数据,这是一个好主意,当我从这个POC移动到真正的程序时,我会记住它。非常感谢:)