程序A:
#include "stdio.h"
int main()
{
int index = 0;
int i = 0;
for (i = 1; i <9988998; i++) {
printf("Current Count is %d\n", index++); Sleep(10 * 999);
}
}
程序B:
namespace process
{
class Program
{
public static void Main(string[] args)
{
RunCommand1(@"d:\code\test\a.exe", "");
Console.ReadKey(true);
}
private static void RunCommand1(string s, string arg) {
using (Process process = new System.Diagnostics.Process())
{
process.StartInfo.FileName = s;
process.StartInfo.Arguments = arg;
// 必须禁用操作系统外壳程序
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true; process.Start(); // 异步获取命令行内容
process.BeginOutputReadLine();
// 为异步获取订阅事件
process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
}
}
private static void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
// 这里仅做输出的示例,实际上您可以根据情况取消获取命令行的内容
// 参考:process.CancelOutputRead()
if (String.IsNullOrEmpty(e.Data) == false)
//this.AppendText(e.Data + "\r\n");
Console.WriteLine(e.Data);
}
public static int RunCommand2(string command, string commandParams)
{
var info = new ProcessStartInfo(command, commandParams);
info.UseShellExecute = false;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
var process = Process.Start(info);
while (!process.HasExited) Thread.Sleep(1000);
return process.ExitCode;
} public static int RunCommand3(string command, string commandParams)
{
var info = new ProcessStartInfo(command, commandParams);
info.UseShellExecute = false;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
var process = Process.Start(info);
var reader = process.StandardOutput;
var results = new StringBuilder();
string lineOut;
while ((lineOut = reader.ReadLine()) != null) {
//results.AppendLine("STDOUT: " + lineOut);
Console.WriteLine(lineOut);
}
reader = process.StandardError;
while ((lineOut = reader.ReadLine()) != null) {
results.AppendLine("STDERR: " + lineOut);
}
while (!process.HasExited) Thread.Sleep(1000);
return process.ExitCode;
}
}
}其中,RunCommand1是我自己写的函数,其他的是网上找的代码,这些代码的共同缺点就是会卡死,究其原因,是因为windows的stdout输出是全缓冲的,只有缓冲区满了才会输出,但我要实现的有一行就输出一行,所以一直实现不了,在网上搜了很多,虽然说是异步获取,但和我的函数大同小异,也必须在缓冲区满了后才能输出,现在的问题是程序A我无法修改,上面只是个例子,实际功能比它复杂很多,但原理一样,也没办法把windows的命令行改为行缓冲,各位高手有什么好办法?
#include "stdio.h"
int main()
{
int index = 0;
int i = 0;
for (i = 1; i <9988998; i++) {
printf("Current Count is %d\n", index++); Sleep(10 * 999);
}
}
程序B:
namespace process
{
class Program
{
public static void Main(string[] args)
{
RunCommand1(@"d:\code\test\a.exe", "");
Console.ReadKey(true);
}
private static void RunCommand1(string s, string arg) {
using (Process process = new System.Diagnostics.Process())
{
process.StartInfo.FileName = s;
process.StartInfo.Arguments = arg;
// 必须禁用操作系统外壳程序
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true; process.Start(); // 异步获取命令行内容
process.BeginOutputReadLine();
// 为异步获取订阅事件
process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
}
}
private static void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
// 这里仅做输出的示例,实际上您可以根据情况取消获取命令行的内容
// 参考:process.CancelOutputRead()
if (String.IsNullOrEmpty(e.Data) == false)
//this.AppendText(e.Data + "\r\n");
Console.WriteLine(e.Data);
}
public static int RunCommand2(string command, string commandParams)
{
var info = new ProcessStartInfo(command, commandParams);
info.UseShellExecute = false;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
var process = Process.Start(info);
while (!process.HasExited) Thread.Sleep(1000);
return process.ExitCode;
} public static int RunCommand3(string command, string commandParams)
{
var info = new ProcessStartInfo(command, commandParams);
info.UseShellExecute = false;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
var process = Process.Start(info);
var reader = process.StandardOutput;
var results = new StringBuilder();
string lineOut;
while ((lineOut = reader.ReadLine()) != null) {
//results.AppendLine("STDOUT: " + lineOut);
Console.WriteLine(lineOut);
}
reader = process.StandardError;
while ((lineOut = reader.ReadLine()) != null) {
results.AppendLine("STDERR: " + lineOut);
}
while (!process.HasExited) Thread.Sleep(1000);
return process.ExitCode;
}
}
}其中,RunCommand1是我自己写的函数,其他的是网上找的代码,这些代码的共同缺点就是会卡死,究其原因,是因为windows的stdout输出是全缓冲的,只有缓冲区满了才会输出,但我要实现的有一行就输出一行,所以一直实现不了,在网上搜了很多,虽然说是异步获取,但和我的函数大同小异,也必须在缓冲区满了后才能输出,现在的问题是程序A我无法修改,上面只是个例子,实际功能比它复杂很多,但原理一样,也没办法把windows的命令行改为行缓冲,各位高手有什么好办法?
使用函数setvbuf(),请参考:http://www.cplusplus.com/reference/cstdio/setvbuf/?kw=setvbuf
第三个参数设置成_IONBF即可实现立即输出
依次运行
reduceBuffer.exe
a.exe
restoreBuffer.exe用C#的Process启动管理这些exe的执行顺序