我正在尝试更改与Mercurial命令行客户端对话的类库,而1.9客户端中的新功能是能够启动服务器并通过标准输入/输出管道与之通信。这是非常有希望的,因为使用Mercurial命令行客户端的一个主要问题是,因为它是用Python编写的,所以有一些开销会激活客户端,即使只是询问它的版本。
然而,有一个问题。到目前为止,我通过读取标准输出/错误检索了命令行客户端的输出,当进程退出时,流刷新,我可以读取流的结尾。
但是,在这种新模式下,进程会将大量文本转储到标准错误/输出,然后等待下一个命令。非常适合减少开销,但由于.NET缓冲了这些流,因此很糟糕。
换句话说,由于进程没有退出,我直到输出该输出的最后一部分:
我有办法吗
如果需要,我可以处理P / Invoke。
这是一个LINQPad概念验证程序,可以说明:
它的作用是启动命令提示符并将其提供给DIR命令,但是请注意,直到循环内已经过了10秒才会输出“C:>”提示在生成目录列表后立即输出命令提示符。
换句话说,这就是命令提示符的作用:
但是,这就是下面的程序:
查看提示
void Main() { string clientExecutablePath =“cmd.exe”;
var psi = new ProcessStartInfo();
psi.FileName = clientExecutablePath;
psi.RedirectStandardError = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
psi.WorkingDirectory = @"C:\";
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
psi.ErrorDialog = false;
psi.StandardErrorEncoding = Encoding.GetEncoding("Windows-1252");
psi.StandardOutputEncoding = Encoding.GetEncoding("Windows-1252");
var p = Process.Start(psi);
var input = p.StandardInput;
var output = p.StandardOutput;
var error = p.StandardError;
Action<StreamReader, string> reader = delegate(StreamReader streamReader, string prefix)
{
string line;
while ((line = streamReader.ReadLine()) != null)
{
Debug.WriteLine(prefix + line);
}
};
IAsyncResult outputReader = reader.BeginInvoke(output, "o: ", null, null);
IAsyncResult errorReader = reader.BeginInvoke(error, "e: ", null, null);
input.Write("dir\n");
input.Flush();
while (!p.HasExited)
{
Thread.Sleep(10000);
input.Close();
}
reader.EndInvoke(outputReader);
reader.EndInvoke(errorReader);
}
答案 0 :(得分:1)
我认为没有办法强制冲洗,但我有几个可能对你有帮助的选择:
HTH,
巴特