【问题标题】:C# process standard output delayC#处理标准输出延迟
【发布时间】:2015-07-01 04:51:46
【问题描述】:

我在 C# 表单中运行 process,其启动信息类似于 Redirect console output to textbox in separate programC# get process output while running,进程运行正常,但输出需要很长时间才能出现在 DataReceived event 中。

我希望在流程生成文本后立即查看文本;根据Process standard output cannot be captured?(第一条评论),我需要等到 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();
}

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

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

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

【问题讨论】:

  • 也许你可以在 BackGroundWorker msdn.microsoft.com/en-us/library/… 中运行你的进程
  • 这对@jmc 有什么帮助?是否有关于 BackgroundWorker 的反馈,它将从可执行文件中获取标准输出?我只看到一个百分比。
  • 你能发布你的可重现代码来运行这个过程吗?然后有人可以找到线索。
  • @emoacht,我已经包含了代码。它(几乎)是 MSN/Stack Overflow 上帮助代码的直接副本(感谢各自的作者)。
  • setvbuf(stdout,NULL,_IONBF,0); 在第一个 printf 命令之前应该会有所帮助。

标签: c# forms process buffer stdout


【解决方案1】:

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

如果已知stdout 不是指交互式设备,则流是完全缓冲的。否则,默认情况下流是行缓冲还是不缓冲取决于库(参见setvbuf)。 Source

因此,除非您可以更改控制台程序源以禁用缓冲,否则在 GUI 程序端什么都做不了。

【讨论】:

  • 非常感谢,它现在就像一个魅力......每一行都很快出现在列表框中。不过有一件事,我不得不改变 process.WaitForExit();做 { application.DoEvents();} while (!process.HasExited);让表单正确响应。
  • @MichaelMiles-Stimson IMO,最好将处理程序附加到process.Exited 而不是process.WaitForExit()while (!process.HasExited)
猜你喜欢
  • 2013-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-12
  • 2014-06-21
  • 2014-06-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多