Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
855 views
in Technique[技术] by (71.8m points)

forms - C# process standard output delay

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 + "
"); });
}

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...