[Mono-list] [Gtk-sharp-list] Check Process state in an GUI app

Chris Howie cdhowie at gmail.com
Mon Jan 21 12:45:51 EST 2008


On Jan 21, 2008 11:58 AM, hellboy195 <hellboy195 at gmail.com> wrote:
> hi,
> I'm currently trying to write a very very simple front-end for ffmpeg with
> gtk#.
> My Code looks like this:
>
> First I check if a file already exits with File.Exits(path)
> MessageDialog -> Overwrite YesNO.
>
> Then the I start ffmpeg with Process.Start().
> Then I want show a MessageDialog if the process finished so I did it like :
>
> while(!proc.HasExited) {}
> MessageDialog -> "Encoding finished";
>
> This is working good but this causes some bugs. E.g: If I do Overwrite it
> "yes". The MessageDialog isn't destroyed until the process finished. If I
> delete this while {} it's working correct but the Message appears
> immediately and not after the process hast Finished. Using if is also not
> that good I suppose :/
>
> Any solution? Thx in advance :)

The problem is that you are waiting for the operation to complete on
the GUI thread.  You have destroyed the dialog, but Gtk cannot
actually remove the dialog from the screen until you give control back
to the main GUI loop.

What you want to do is either add an idle handler or spin off another
thread to take care of it.  An idle handler would probably be easiest
for your purpose:

// Message dialog code
Process proc = ...;
GLib.Idle.Add(delegate {
    if (proc.HasExited) {
        // Show dialog.
        return false; // Remove this delegate from the idle list.
    }

    return true; // Run this delegate again when idle.
});

Note that this approach can burn quite a bit of CPU running the idle
delegate.  You may want to try attaching an event handler to
Process.Exited instead:

proc.EnableRaisingEvents = true;
proc.Exited += delegate {
    Application.Invoke(delegate {
        // Show dialog.
    });
};

Note that you must call Application.Invoke because the Exited event
handler will not be running on the GUI thread, and you should not
touch the GUI from other threads.  Application.Invoke puts a delegate
in a queue to be executed on the GUI thread the next time the main
loop is entered.

-- 
Chris Howie
http://www.chrishowie.com
http://en.wikipedia.org/wiki/User:Crazycomputers


More information about the Mono-list mailing list