我需要使用标准输入和标准输出与外部可执行文件(ampl.exe)进行通信。这个exe在几分钟内进行计算,在控制台中有一些显示。它有一个提示,所以我可以在计算完成后立即使用其标准输入连续启动计算。
外部exe启动为:
var myProcess = new Process();
myProcess.StartInfo = new ProcessStartInfo("ampl.exe");
myProcess.StartInfo.CreateNoWindow = true;
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.StartInfo.RedirectStandardError = true;
myProcess.StartInfo.RedirectStandardInput = true;
myProcess.Start();
我使用myProcess.StandardInput和myProcess.StandardOutput(同步方式)与它进行通信。
我使用标准输入来启动计算,例如:
myProcess.StandardInput.WriteLine("solve;");
我想等待solve语句结束,在文件中获取结果,准备新的计算输入文件,然后启动第二次求解。
我的问题是我现在知道第一次计算何时完成,即exe在其标准输入中等待新命令的时间。 我发现的唯一方法是添加一个特定的显示命令,并等待它成为标准输出:
myProcess.StandardInput.WriteLine("solve;");
myProcess.StandardInput.WriteLine("print 'calculDone';");
string output = myProcess.StandardOutput.ReadLine();
while (!output.Contains("calculDone"))
{
output = myProcess.StandardOutput.ReadLine();
}
还有另一种方法可以避免使用此显示命令来执行此操作吗?
编辑:遵循建议,我尝试了异步方式。但是我仍然需要打印'CalculDone'以了解解决方案声明何时结束。我没有在进程的标准输出中得到ampl.exe(即'ampl:')的提示。
AutoResetEvent eventEnd = new AutoResetEvent(false);
var myProcess = new Process();
myProcess.StartInfo = new ProcessStartInfo("ampl.exe");
myProcess.StartInfo.CreateNoWindow = true;
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.StartInfo.RedirectStandardError = true;
myProcess.StartInfo.RedirectStandardInput = true;
myProcess.EnableRaisingEvents = true;
myProcess.OutputDataReceived += (sender, e) =>
{
if (e.Data == "commandDone")
{
eventEnd.Set();
}
else if (e.Data != null)
{
Console.WriteLine("ampl: {0}", e.Data);
}
};
myProcess.Start();
myProcess.BeginOutputReadLine();
myProcess.StandardInput.WriteLine("solve;");
myProcess.StandardInput.WriteLine("print 'commandDone';");
eventEnd.WaitOne();
答案 0 :(得分:1)
最好的选择是使用Processs.OutputDataReceived
事件而不是紧密的while循环。这就像事件异步模式,您启动异步任务并等待事件回调告诉您已完成。异步任务的继续将放在事件处理程序中。记得在第一次关闭时取消订阅事件处理程序,否则当你不想要它时它会被触发。
我从未尝试过的另一个选项是Process.WaitForInputIdle()
方法,但我不确定这是否适用于您的特定情况。如果是,则不需要在输入流中写入任何内容。