I'm creating a test program that reports back a command line tool's output to a text box in real time to understand how it works, and learn the groundwork for use in a future project. My current code simply pings the local loop back IP address five times and sends the output to a text box. Initially I had issues with the UI locking up during the 'ping', so I've incorporated a background worker so the UI remains responsive while the 'ping' command runs. However my issue is that I can't seem to get the ping output to display in the text box in real time (eg, so each of the 5 ping response appears in the text box as they would in a command prompt). Currently nothing happens for 5 seconds then the complete 'ping' results display in one go:
Here is my current code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
bgw.WorkerReportsProgress = true;
bgw.WorkerSupportsCancellation = true;
bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
}
//////////////////////////////////////////////////////////
// Begin ping test
//////////////////////////////////////////////////////////
private void btnPing_Click(object sender, EventArgs e)
{
if (bgw.IsBusy != true)
{
bgw.RunWorkerAsync();
}
}
//////////////////////////////////////////////////////////
// Background worker
//////////////////////////////////////////////////////////
private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
Process proc = new Process();
proc.StartInfo.FileName = "ping";
proc.StartInfo.Arguments = "127.0.0.1 -n 5";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
using (StreamReader reader = proc.StandardOutput)
{
string stdout = reader.ReadToEnd();
this.Invoke((MethodInvoker)delegate
{
txtOutput.AppendText(stdout);
});
}
proc.WaitForExit();
}
//////////////////////////////////////////////////////////
// Background worker completed
//////////////////////////////////////////////////////////
private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled == true)
{
btnPing.Text = "Canceled!";
}
else if (e.Error != null)
{
btnPing.Text = "Error: " + e.Error.Message;
}
else
{
btnPing.Text = "Success!";
}
}
}
I have looked at similar posts and MSDN references but drawn blanks as either the techniques are beyond my current level of understanding, or seem to be unrelated. A pointer in the right direction would be appreciated.