Darajan
Darajan

Reputation: 883

Returning a value from Dispatcher.RunAsync() to background thread

I'm using Dispatcher.RunAsync() to show a MessageDialog from a background thread. But I'm having trouble figuring out how to get a result returned.

My code:

            bool response = false;

        await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
             async () =>
             {
                 DebugWriteln("Showing confirmation dialog: '" + s + "'.");
                 MessageDialog dialog = new MessageDialog(s);

                 dialog.Commands.Add(new UICommand(GetLanguageString("Util_DialogButtonYes"), new UICommandInvokedHandler((command) => {
                     DebugWriteln("User clicked 'Yes' in confirmation dialog");
                     response = true;
                 })));

                 dialog.Commands.Add(new UICommand(GetLanguageString("Util_DialogButtonNo"), new UICommandInvokedHandler((command) =>
                 {
                     DebugWriteln("User clicked 'No' in confirmatoin dialog");
                     response = false;
                 })));
                 dialog.CancelCommandIndex = 1;
                 await dialog.ShowAsync();
             });
        //response is always False
        DebugWriteln(response);

Is there anyway to do it like this? I thought about maybe returning the value from inside RunAsync() but function is void.

Upvotes: 3

Views: 2917

Answers (1)

MBender
MBender

Reputation: 5650

You could make use of the ManualResetEvent class.

This is my helper method for returning values from the UI thread to other threads. This is for Silverlight! As such, you probably can't copy-paste it to your application and expect it to work, BUT hopefully it'll give you an idea on how to proceed.

    public static T Invoke<T>(Func<T> action)
    {
        if (Dispatcher.CheckAccess())
            return action();
        else
        {
            T result = default(T);
            ManualResetEvent reset = new ManualResetEvent(false);
            Dispatcher.BeginInvoke(() =>
            {
                result = action();
                reset.Set();
            });
            reset.WaitOne();
            return result;
        }
    }

Upvotes: 4

Related Questions