CoreDispatcher proporciona el planificador de eventos (Windows Runtime core event message dispatcher) en tiempo de ejecución de Windows.
Se encarga de procesar los mensajes de ventanas y el envío de los eventos a los clientes. La clase Dispatcher proporciona los servicios para administrar los hilos de un subproceso y, como veremos en este artículo, del hilo encargado de la interfaz de usuario.

Que es el Dispatcher?

El Dispatcher proporciona servicios para la gestión de trabajos para un hilo o subproceso. El Dispatcher es un objeto asociado con la clase CoreDispatcher.

La clase CoreDispatcher proporciona el distribuidor de eventos del runtime de Windows en tiempo de ejecución de Windows. Se encarga de procesar los mensajes del sistema y el envío de los eventos a los métodos suscritos a estos eventos. Esto significa que la clase CoreDispatcher está asociada a aplicaciones de interfaz de usuario.

Cual es el uso del Dispatcher?

En programación asíncrona, el Dispatcher interactúa con el hilo responsable de la interfaz (UI Thread) en lugar de hacerlo con el Worker Thread (comúnmente utilizado para tareas en background por las que el usuario no debe esperar para seguir utilizando la aplicación). Recordemos que en los programas Win32, generalmente se utiliza un hilo principal para gestionar la interfaz de usuario y suele ser síncrono.

A la hora podemos encontrarnos con el siguiente error a la hora de realizar actualizaciones sobre la IU de la aplicación: The application called an interface that was marshalled for a different thread

Exception

Cómo ejecutar codigo en el Hilo responsible de la interaz (UI thread)?

Con el objetivo de ejecutar código en el hilo responsable de la interaz, la clase CoreDispatcher nos proporciona el método RunAsync. Este método transforma el codigo de actualizacion de la interaz de usuario desde un Worker Thread al hilo adecuado, el UI Thread.

Por ejemplo, en el siguiente ejemplo, el evento ReadingChanged de un Acelerómetro. Cuando se ejecuta la lectura del acelerometro se muestra en la interfaz de la aplicación. Para actualizarlo, se utilizar el Dispatcher.

private async void ReadingChanged(object sender, AccelerometerReadingChangedEventArgs e)
{
   await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
   {
     AccelerometerReading reading = e.Reading;
     ScenarioOutput_X.Text = String.Format(“{0,5:0.00}”, reading.AccelerationX);
     ScenarioOutput_Y.Text = String.Format(“{0,5:0.00}”, reading.AccelerationY);
     ScenarioOutput_Z.Text = String.Format(“{0,5:0.00}”, reading.AccelerationZ);
   });
}

La conexión con el valor del Dispatcher (el evento/acción que requiere acceso al UI thread para su ejecución) no está disponible en tiempo de diseño y esto puede causar errores si hemos creado un control personalizado o un control de usuario que utilice valores del Dispatcher si se accede al mismo desde un entorno de diseño. En lugar de acceder a la vista XAML (XAML design preview) nos lanzará la siguiente excepción:

 

Solución: Introducción a la clase DesignMode

El namespace Windows.ApplicationModel proporciona la clase estáticoa DesignMode que permite detector si tu aplicación está o no en modo diseño en el Visual Designer. Esta clase tiene la propiedad DesignModeEnabled de tipo boolean. Utilizando esta propiedad podemos incluir una condicion de modo que el metodo no llame al código cuando DesignModeEnabled is True.

El código debería ser algo así:

private async void MyCustomControl_Loaded(object sender, RoutedEventArgs e)
  {
  if (!Windows.ApplicationModel.DesignMode.DesignModeEnabled)
    {
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
    {
      txtMsgCount.Text = await GetInboxBubbleCountAsync();
      txtFirstName.Text = await GetFirstNameAsync();
      txtLastName.Text = await GetLastNameAsync();
      imgProfilePic.Source = new BitmapImage(new Uri(await GetProfilePictureUrlAsync();));
    });
  }
}

En resumen, debemos implementar este tipo de condiciones para evitar la ejecución en tiempo de diseño si requiere acceso al UI Thread.