Re: Updating GUI from an asynchronous thread

Ian Norton <[email protected]> Wed, 3 Apr 2013 10:59:31 +0100
Newsgroups gmane.comp.gnome.winforms
Message-ID <CAGUnuBHyyNOnXRFTJ_XZxnNuWVxUp+mqisYbvHxeWtCbnxnv_Q@mail.gmail.com>
--===============1835895103==
Content-Type: multipart/alternative; boundary=047d7b5d9c6f0cc0c104d971e9ab

--047d7b5d9c6f0cc0c104d971e9ab
Content-Type: text/plain; charset=ISO-8859-1

Reading your program, it looks like you only run the gtk main loop when
your child gives you data.

Also, that is gtk, this is the win forms list :-)
On 2 Apr 2013 21:18, "Neil Thackeray" <[email protected]> wrote:

> 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(); });
>         }
> }
> }
> ______________________________**_________________
> Mono-winforms-list maillist  -  Mono-winforms-list@lists.**ximian.com<[email protected]>
> http://lists.ximian.com/**mailman/listinfo/mono-**winforms-list<http://lists.ximian.com/mailman/listinfo/mono-winforms-list>
>

--047d7b5d9c6f0cc0c104d971e9ab
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<p dir=3D"ltr">Reading your program, it looks like you only run the gtk mai=
n loop when your child gives you data.</p>
<p dir=3D"ltr">Also, that is gtk, this is the win forms list :-) </p>
<div class=3D"gmail_quote">On 2 Apr 2013 21:18, &quot;Neil Thackeray&quot; =
&lt;<a href=3D"mailto:[email protected]">[email protected]</a>&gt; wrote:=
<br type=3D"attribution"><blockquote class=3D"gmail_quote" style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I&#39;m having trouble getting the output from a command line program to ap=
pear in the main window of a form. For simplicity I&#39;m just trying to ge=
t it to appear in a label for now. When I run the function RunIt nothing fr=
om stdout of the child process appears in the label, but ConsoleWriteline s=
eems to pick it up just fine. When it gets down to the while loop it update=
s the label perfectly fine.<br>

<br>
I&#39;ve also noticed that the form seems to be locked while the child proc=
ess 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.<br>

<br>
Any suggestions are appreciated.<br>
<br>
Thanks<br>
<br>
namespace windowtest<br>
{<br>
public partial class MainWindow: Gtk.Window<br>
{<br>
=A0 =A0 public MainWindow (): base (Gtk.WindowType.Toplevel)<br>
=A0 =A0 {<br>
=A0 =A0 =A0 =A0 =A0Build ();<br>
=A0 =A0 }<br>
<br>
=A0 =A0 protected void OnDeleteEvent (object sender, DeleteEventArgs a)<br>
=A0 =A0 {<br>
=A0 =A0 =A0 =A0 Application.Quit ();<br>
=A0 =A0 =A0 =A0 a.RetVal =3D true;<br>
=A0 =A0 }<br>
<br>
=A0 =A0 =A0 =A0 public void RunIt ()<br>
=A0 =A0 =A0 =A0 {<br>
=A0 =A0 =A0 =A0 =A0 =A0 string prog =3D @&quot;C:/Program Files (x86)/Progr=
am/Program.exe&quot;;<br>
=A0 =A0 =A0 =A0 =A0 =A0 // Start the child process.<br>
=A0 =A0 =A0 =A0 =A0 =A0 System.Diagnostics.Process p =3D new System.Diagnos=
tics.Process();<br>
=A0 =A0 =A0 =A0 =A0 =A0 p.StartInfo.UseShellExecute =3D false;<br>
=A0 =A0 =A0 =A0 =A0 =A0 p.StartInfo.Arguments =3D &quot;Program Arguments&q=
uot;;<br>
=A0 =A0 =A0 =A0 =A0 =A0 p.StartInfo.<u></u>RedirectStandardOutput =3D true;=
<br>
=A0 =A0 =A0 =A0 =A0 =A0 p.StartInfo.FileName =3D prog;<br>
=A0 =A0 =A0 =A0 =A0 =A0 p.StartInfo.CreateNoWindow =3D true;<br>
=A0 =A0 =A0 =A0 =A0 =A0 p.EnableRaisingEvents =3D true;<br>
=A0 =A0 =A0 =A0 =A0 =A0 // Redirect the output stream of the child process.=
<br>
=A0 =A0 =A0 =A0 =A0 =A0 p.OutputDataReceived +=3D new DataReceivedEventHand=
ler(<br>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 delegate(object sender, DataReceivedEventAr=
gs e)<br>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 {<br>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!String.IsNullOrEmpty(e.Data)<u=
></u>)<br>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 {<br>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 lblTest.Text =3D e.Data;<br=
>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 while (Gtk.Application.Even=
tsPending ())<br>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Gtk.Application.Run=
Iteration ();<br>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Console.WriteLine(e.Data);<=
br>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }<br>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }<br>
=A0 =A0 =A0 =A0 =A0 =A0 );<br>
=A0 =A0 =A0 =A0 =A0 =A0 p.Start();<br>
=A0 =A0 =A0 =A0 =A0 =A0 p.BeginOutputReadLine();<br>
=A0 =A0 =A0 =A0 =A0 =A0 p.WaitForExit();<br>
=A0 =A0 =A0 =A0 =A0 =A0 p.Close();<br>
=A0 =A0 =A0 =A0 =A0 =A0 int i =3D 0;<br>
=A0 =A0 =A0 =A0 =A0 =A0 while (i &lt; 20)<br>
=A0 =A0 =A0 =A0 =A0 =A0 {<br>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 lblTest.Text =3D i.ToString();<br>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 while (Gtk.Application.EventsPending ())<br=
>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Gtk.Application.RunIteration ();<br=
>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Console.WriteLine(i.ToString()<u></u>);<br>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 i++;<br>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 System.Threading.Thread.Sleep (100);<br>
=A0 =A0 =A0 =A0 =A0 =A0 }<br>
=A0 =A0 =A0 =A0 =A0 =A0 lblTest.Text =3D &quot;Test&quot;;<br>
=A0 =A0 =A0 =A0 }<br>
<br>
=A0 =A0 =A0 =A0 protected void OnButton4Clicked (object sender, EventArgs e=
)<br>
=A0 =A0 =A0 =A0 {<br>
=A0 =A0 =A0 =A0 =A0 =A0 System.ComponentModel.<u></u>BackgroundWorker bw =
=3D new System.ComponentModel.<u></u>BackgroundWorker();<br>
=A0 =A0 =A0 =A0 =A0 =A0 bw.WorkerSupportsCancellation =3D true;<br>
=A0 =A0 =A0 =A0 =A0 =A0 bw.DoWork +=3D new System.ComponentModel.<u></u>DoW=
orkEventHandler(TestInvoke)<u></u>;<br>
=A0 =A0 =A0 =A0 =A0 =A0 if (bw.IsBusy !=3D true)<br>
=A0 =A0 =A0 =A0 =A0 =A0 {<br>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 bw.RunWorkerAsync();<br>
=A0 =A0 =A0 =A0 =A0 =A0 }<br>
=A0 =A0 =A0 =A0 }<br>
=A0 =A0 =A0 =A0 private void TestInvoke(object sender, System.ComponentMode=
l.<u></u>DoWorkEventArgs e)<br>
=A0 =A0 =A0 =A0 {<br>
=A0 =A0 =A0 =A0 =A0 =A0 Application.Invoke(delegate{ RunIt(); });<br>
=A0 =A0 =A0 =A0 }<br>
}<br>
}<br>
______________________________<u></u>_________________<br>
Mono-winforms-list maillist =A0- =A0<a href=3D"mailto:Mono-winforms-list@li=
sts.ximian.com" target=3D"_blank">Mono-winforms-list@lists.<u></u>ximian.co=
m</a><br>
<a href=3D"http://lists.ximian.com/mailman/listinfo/mono-winforms-list" tar=
get=3D"_blank">http://lists.ximian.com/<u></u>mailman/listinfo/mono-<u></u>=
winforms-list</a><br>
</blockquote></div>

--047d7b5d9c6f0cc0c104d971e9ab--

--===============1835895103==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Mono-winforms-list maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-winforms-list

--===============1835895103==--