C#处理标准输出延迟

Mic*_*son 1 c# forms buffer stdout process

从 C# 表单中,我正在运行一个进程,其启动信息类似于将控制台输出重定向到单独程序中的文本框,并且C# 在运行时获取进程输出,该进程运行正确,但输出需要很长时间才能出现在DataReceived 事件中。

我希望在流程生成后立即看到文本;根据流程标准输出无法捕获?(第一条评论)我需要等到 2 到 4 kb 的缓冲区填满后才能触发事件。

根据要求,这是代码:

void pcs_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
    if (!string.IsNullOrEmpty(e.Data)) 
        textBox1.BeginInvoke((Action)delegate { textBox1.AppendText(text + "\n"); });
}

private void LER_Go_Click(object sender, EventArgs e)
{
    // variables LiDARExtRep contains the full path to an executable file
    // that runs in DOS and produces verbose output.
    // LER_Path.Text is the parameter passed to LiDARExtRep (only one arg for this example)
    ProcessStartInfo pStartInfo = new ProcessStartInfo(LiDARExtRep, LER_Path.Text);    
    pStartInfo.UseShellExecute = false;
    pStartInfo.ErrorDialog = false;
    pStartInfo.RedirectStandardError = true;
    pStartInfo.RedirectStandardInput = true;
    pStartInfo.RedirectStandardOutput = true;
    pStartInfo.CreateNoWindow = true;

    System.Diagnostics.Process pcs = new System.Diagnostics.Process();
    pcs.StartInfo = pStartInfo;

    bool pStarted = pcs.Start();

    pcs.OutputDataReceived += new DataReceivedEventHandler(pcs_OutputDataReceived);

    pcs.BeginOutputReadLine();
    pcs.WaitForExit();
}
Run Code Online (Sandbox Code Playgroud)

我没有看到它有什么特别之处,它与我引用的示例完全相同......"Dir","/b/s"构造函数中的简单应该产生相同的结果。

有没有办法将缓冲区减少到几个字节,或者有更好的方法来执行命令行工具并“实时”接收输出?

背景:我用 C++ 编写了一些命令行程序,它们工作得很好,但是年轻一代似乎害怕 DOS,所以我正在创建一个表单(GUI)来收集这些工具的参数,因为它看起来试图在 C++ 中的每个程序上放置一个 GUI。如果我无法获得实时响应,我将不得不UseShellExecute = true;显示命令窗口。

use*_*407 5

缓冲发生在控制台程序端。默认情况下,stdout如果已知要重定向,则完全缓冲:

如果stdout已知不涉及交互设备,则流被完全缓冲。否则,默认情况下流是行缓冲还是不缓冲取决于库(请参阅setvbuf)。来源

因此,除非您可以更改控制台程序源以禁用缓冲,否则在 GUI 程序端无法执行任何操作。