[Mono-winforms-list] Updating GUI from an asynchronous thread
Neil Thackeray
neilt at illinois.edu
Tue Apr 2 19:36:56 UTC 2013
I'm having trouble getting the output from a command line program to
appear in the main window of a form. For simplicity I'm just trying to
get it to appear in a label for now. When I run the function RunIt
nothing from stdout of the child process appears in the label, but
ConsoleWriteline seems to pick it up just fine. When it gets down to the
while loop it updates the label perfectly fine.
I've also noticed that the form seems to be locked while the child
process is running. When I was just using BackgroundWorker without
Application.Invoke the form updated from the child process and the while
loop, but the update was spotty and the application crashed sporadically.
Any suggestions are appreciated.
Thanks
namespace windowtest
{
public partial class MainWindow: Gtk.Window
{
public MainWindow (): base (Gtk.WindowType.Toplevel)
{
Build ();
}
protected void OnDeleteEvent (object sender, DeleteEventArgs a)
{
Application.Quit ();
a.RetVal = true;
}
public void RunIt ()
{
string prog = @"C:/Program Files (x86)/Program/Program.exe";
// Start the child process.
System.Diagnostics.Process p = new
System.Diagnostics.Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.Arguments = "Program Arguments";
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = prog;
p.StartInfo.CreateNoWindow = true;
p.EnableRaisingEvents = true;
// Redirect the output stream of the child process.
p.OutputDataReceived += new DataReceivedEventHandler(
delegate(object sender, DataReceivedEventArgs e)
{
if (!String.IsNullOrEmpty(e.Data))
{
lblTest.Text = e.Data;
while (Gtk.Application.EventsPending ())
Gtk.Application.RunIteration ();
Console.WriteLine(e.Data);
}
}
);
p.Start();
p.BeginOutputReadLine();
p.WaitForExit();
p.Close();
int i = 0;
while (i < 20)
{
lblTest.Text = i.ToString();
while (Gtk.Application.EventsPending ())
Gtk.Application.RunIteration ();
Console.WriteLine(i.ToString());
i++;
System.Threading.Thread.Sleep (100);
}
lblTest.Text = "Test";
}
protected void OnButton4Clicked (object sender, EventArgs e)
{
System.ComponentModel.BackgroundWorker bw = new
System.ComponentModel.BackgroundWorker();
bw.WorkerSupportsCancellation = true;
bw.DoWork += new
System.ComponentModel.DoWorkEventHandler(TestInvoke);
if (bw.IsBusy != true)
{
bw.RunWorkerAsync();
}
}
private void TestInvoke(object sender,
System.ComponentModel.DoWorkEventArgs e)
{
Application.Invoke(delegate{ RunIt(); });
}
}
}
More information about the Mono-winforms-list
mailing list