3

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.

Darajan
  • 868
  • 1
  • 9
  • 23
  • 1
    http://stackoverflow.com/a/17275107/1230188 – Farhan Ghumra Jul 16 '13 at 09:28
  • 1
    You should try to avoid `CoreDispatcher.RunAsync` as much as possible. That method makes your UI thread like a "service" that your background threads use. A cleaner design is to have your background threads be the "services" that your UI thread uses. Then you just need `async`/`await` and never have to manually dispatch delegates at all. – Stephen Cleary Jul 16 '13 at 12:09
  • I have to agree with Stephen. The code I posted was from a SL application written in VS2010, so I didn't have access to `async`/`await` (I found no use for that method once I started working on a new SL app in VS2012). That said, it can still be beneficial to grab the occasional textbox value or something from the UI every now and again in another thread. – MBender Jul 17 '13 at 09:45

1 Answers1

4

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;
        }
    }
MBender
  • 5,395
  • 1
  • 42
  • 69