5 Comments
  •   Posted in: 
  • UWP

The Release Preview of Windows 8 broke some things but fortunately there’s a quite good migration guide available which highlight most of the changes (Word document):

Migrating your Windows 8 Consumer Preview app to Windows 8 Release Preview

Unfortunately the guide seems to have missed some changes, like the removing of CoreDispatcher.Invoke and BeginInvoke –methods.

Breaking Change between Consumer Preview and Release Preview:

The following code worked in WinRT app with Consumer Preview:

dispatcher.Invoke(CoreDispatcherPriority.Normal, (s, e) => action(), dispatcher, null);

But the Invoke-method is now gone. If it’s OK that the action is executed asynchronously in UI thread (like BeginInvoke), this seems to be the way to go in Release Preview + WinRT combination:

dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => action());

But if the invoke must happen synchronously (like Invoke), async / await can be used:

await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => action());

UIDispatcher - A helper class which allows the synchronous and asynchronous execution of methods in UI thread:

Here’s a complete UIDispatcher-class which can be used to execute actions in UI thread:

using System;
using System.Threading.Tasks;
using Windows.UI.Core;
using Windows.UI.Xaml;

namespace Helpers
{
    public static class UIDispatcher
    {
        private static CoreDispatcher dispatcher;

        public static void Initialize()
        {
            dispatcher = Window.Current.Dispatcher;
        }

        public static void BeginExecute(Action action)
        {
            if (dispatcher.HasThreadAccess)
                action();

            else dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => action());
        }

        public static void Execute(Action action)
        {
            InnerExecute(action).Wait();
        }

        private static async Task InnerExecute(Action action)
        {
            if (dispatcher.HasThreadAccess)
                action();

            else await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => action());
        }
    }
}

Initialization:

Call the Initialize-method at the application startup, for example in App.xaml.cs's OnLaunched-method:

// Place the frame in the current Window and ensure that it is active
            Window.Current.Content = rootFrame;
            Window.Current.Activate();

            UIDispatcher.Initialize();

Without this the UIDispatcher won't work.

Invoking actions on UI thread:

After the UIDispatcher has been initialized, the Execute-method can be used to invoke actions in UI thread synchronously and BeginExecute to invoke action asynchronously:

ThreadPool.RunAsync(operation => UIDispatcher.Execute(() => this.Test.Text = "hello!"));

Links:

Here’s a good explanation by Jon Skeet about the differences of BeginInvoke and Invoke.