【发布时间】:2018-02-28 23:04:37
【问题描述】:
我正在尝试在 .NET 中启动子进程并将其输出重定向到命名管道。在子进程中写入标准输出的尝试应该被阻塞,直到客户端实际从命名管道中读取。
这是我的代码:
using System;
using System.Diagnostics;
using System.IO.Pipes;
namespace psub
{
class Program
{
static void Main(string[] args)
{
var pipeName = "testpipe"; // Guid.NewGuid().ToString();
Console.WriteLine($@"\\.\pipe\{pipeName}");
var psi = new ProcessStartInfo()
{
FileName = "ping",
Arguments = "google.com",
UseShellExecute = false,
RedirectStandardOutput = true
};
using (var pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.Out))
using (var process = new Process { StartInfo = psi })
{
pipeServer.WaitForConnection();
process.Start();
process.StandardOutput.BaseStream.CopyTo(pipeServer);
process.WaitForExit();
}
}
}
}
当我启动这个可执行文件时,它在pipeServer.WaitForConnection(); 处阻塞,正如预期的那样。然后我打开cmd.exe 并运行type \\.\pipe\testpipe,尝试从命名管道[1] 中读取。
这会导致以下错误(在 cmd 会话中):
All pipe instances are busy.
此外,在 C# 程序中,pipeServer.WaitForConnection 完成,然后执行继续到 ...CopyTo(pipeServer),它会爆炸:
Unhandled Exception: System.IO.IOException: Pipe is broken.
我不明白为什么会发生 All pipe instances are busy. 错误。
据我了解,有一个服务器(在 C# 程序中实例化)将写入命名管道。一旦执行到达CopyTo,数据就会被传送到程序的单个阻塞线程上的命名管道服务器。
还有一个命名管道客户端(type \\.\pipe\testpipe 进程),它将释放服务器尝试写入的数据的命名管道。
那么为什么会出现“所有管道实例都忙”的错误呢?
我尝试将new NamedPipeServerStream(pipeName, PipeDirection.Out) 调整为new NamedPipeServerStream(pipeName, PipeDirection.Out, 2) 以及其他一些调整,但没有成功,但对问题所在或如何解决问题没有任何真正的了解。有人可以像我五岁一样解释一下吗?
[1]:目标是模拟 UNIX shell 中可用的 process substitution 功能,因此我必须能够从 \\.\pipe\<some file name> 中读取,而不是使用 C++ 或 .NET 为管道。
【问题讨论】:
-
Pipe is brokenon write 说管道句柄已经关闭 -
@RbMm 是的,我明白这一点,但它为什么死了?问题是原始的
All pipe instances are busy.错误消息,导致管道死亡,但为什么从管道读取完全是错误?
标签: c# winapi named-pipes