Executar código no thread da interface do usuário no WinRT

Como posso executar o código no thread de interface do usuário no WinRT (Windows 8 Metro)?

O método Invoke não existe.

   

É mais fácil obter diretamente o CoreWindow do segmento não-UI. O código a seguir funcionará em todos os lugares, mesmo quando GetForCurrentThread() ou Window.Current retornar null .

 CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, ); 

por exemplo:

 CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { // Your UI update code goes here! }); 

Você precisará referenciar o namespace Windows.ApplicationModel.Core :

 using Windows.ApplicationModel.Core; 

Usar:

Do seu thread de interface do usuário, execute:

 var dispatcher = Windows.UI.Core.CoreWindow.GetForCurrentThread().Dispatcher; 

De seu plano de fundo (não thread de interface do usuário)

 dispatcher.RunAsync(DispatcherPriority.Normal, ); 

Isso deve funcionar em CP e versões posteriores.

Usar:

 this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => Frame.Navigate(typeof(Welcome), this)); 

Funciona para mim.

Esta é uma maneira muito mais fácil na minha opinião.

Obtenha o TaskScheduler associado à interface do usuário.

  var UISyncContext = TaskScheduler.FromCurrentSynchronizationContext(); 

Em seguida, inicie uma nova tarefa e no UISyncContext acima.

  Task.Factory.StartNew(() => { /* Do your UI stuff here; */}, new System.Threading.CancellationToken(), TaskCreationOptions.PreferFairness, UISyncContext); 

O DispatcherTimer também é uma opção.

Eu usei para o código que deve ser executado no Xaml-designer (CoreWindow.Dispatcher, … não estão disponíveis no UWP-designer)

 var localTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(0) }; localTimer.Tick += (timer, e) => { (timer as DispatcherTimer).Stop(); action(); }; localTimer.Start(); 

Aviso Legal:
Devo notar que esta deve ser uma opção de último recurso se todos os outros falharem.

No UWP, eu estava tendo problema ao tentar definir a propriedade Source do controle CaptureElement (que é definido em XAML), estava reclamando sobre estar preparado em um thread diferente, mesmo que eu estivesse tentando configurá-lo a partir do código que foi invocado por um Page_Loaded manipulador de events. Eu acabei usando isso para contornar isso:

 previewControl.Dispatcher.TryRunAsync(CoreDispatcherPriority.Normal, () => { previewControl.Source = _mediaCapture; }).GetAwaiter().GetResult();