views:

121

answers:

1

Unfortunately, Application.Invoke() is asynchronous:

private string ThreadFunction(int i)
{
    string result = null;

    Gtk.Application.Invoke(delegate
    {
        OutputStringToUserInterface("i = " + i.ToString());
        result = GetStringFromUserInterface();
    });

    return result;
}

This means that in this example ThreadFunction() proceeds immediately after calling Application.Invoke(), resulting in an probably undefined state of the result string. -- Typically ThreadFunction() will be faster and will return with the old value (i.e. null).


This is a workaround using ManualResetEvent to make Application.Invoke() synchronous:

private string ThreadFunction(int i)
{
    string result = null;

    ManualResetEvent ev = new ManualResetEvent(false);

    Gtk.Application.Invoke(delegate
    {
        OutputStringToUserInterface("i = " + i.ToString());
        result = GetStringFromUserInterface();

        ev.Set();
    });

    ev.WaitOne();

    return result;
}

This way, ThreadFunction() waits until Application.Invoke() returns, like it would do using WinForms Control.Invoke().

EDIT: Better example code


Now my question: Is there a better solution (in respect to performance/resource consumption)?

+2  A: 

Well, yes, there's no reason to wait for the delegate to execute to get the proper return value. Fix:

int result = i + 1;

And it's okay to let the OutputStringToUserInterface() execute asynchronously, assuming you don't call ThreadFunction() so often that it floods the UI thread with requests.

If your real code actually depends on a return value from a function that must run on the UI thread then, no, you can't make it faster. Clearly, that's something you really want to avoid.

Hans Passant
Ok. Maybe the example wasn't that good. I improved it in the question.
ulrichb
Well, the last paragraph in my post still applies.
Hans Passant
OK +1. So you don't think there is a better alternative (concerning resource consumption) than the one suggested above?
ulrichb
Resource consumption? A ManualResetEvent is very cheap.
Hans Passant