[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