C#进程标准输出延迟 [英] C# process standard output delay

查看:218
本文介绍了C#进程标准输出延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



根据要求,这是代码:

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

private void LER_Go_Click(object sender,EventArgs e)
{
//变量LiDARExtRep包含可执行文件的完整路径
//在DOS下运行并生成详细的输出。
// LER_Path.Text是传递给LiDARExtRep的参数(本例中只有一个参数)
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; 并显示命令窗口。

解决方案

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


如果<已知code> stdout 指的不是交互设备,而是流被完全缓冲。否则,默认情况下,数据流是依赖于数据库的,而不管该数据流是否为行缓冲未缓冲(请参阅 setvbuf )。 来源


因此,除非您可以改变控制台程序源以禁用缓冲,否则在GUI程序端无法完成。


From a C# form I am running a process with start info similar to Redirect console output to textbox in separate program and C# get process output while running, the process runs correctly however the output takes a long time to appear in the DataReceived event.

I would like to see the text as soon as the process generates it; according to Process standard output cannot be captured? (first comment) I need to wait until a buffer of 2 to 4 kb to fill before the event is fired.

As requested this is the code:

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();
}

I don't see anything special about it, it's exactly the same as the examples I referenced... a simple "Dir","/b/s" in the constructor should produce the same results.

Is there a way to diminish the buffer to a few bytes or a better way to execute a command line tool and receive the output 'real time'?

Background: I wrote a number of command line programs in C++, which work great, but the younger generation seem scared of DOS, so I am creating a form (GUI) to collect the parameters for these tools as it seems a lot less work than trying to put a GUI on each program in C++. If I can't get real time responses I will have to UseShellExecute = true; and show the command window.

解决方案

The buffering happens on console program end. By default, stdout is fully buffered if known to be redirected:

If stdout is known to not refer to an interactive device, the stream is fully buffered. Otherwise, it is library-dependent whether the stream is line buffered or not buffered by default (see setvbuf). Source

So, unless you can alter the console program source to disable buffering, nothing can be done on GUI program side.

这篇关于C#进程标准输出延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆