it-swarm.com.ru

Выполнить код в потоке пользовательского интерфейса в WinRT

Как запустить код в потоке пользовательского интерфейса в WinRT (Windows 8 Metro)?

Метод Invoke не существует.

64
ofer

Проще непосредственно получить CoreWindow из потока, не являющегося пользовательским интерфейсом. Следующий код будет работать везде, даже когда GetForCurrentThread() или Window.Current возвращают null.

CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
    <lambda for your code which should run on the UI thread>);

например:

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

Вам нужно сослаться на пространство имен Windows.ApplicationModel.Core:

using Windows.ApplicationModel.Core;
77
Cœur

Использование:

Из вашего потока пользовательского интерфейса выполните:

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

Из вашего фона (не пользовательский поток)

dispatcher.RunAsync(DispatcherPriority.Normal, 
    <lambda for your code which should run on the UI thread>);

Это должно работать как на CP, так и на более поздних сборках.

69
Larry Osterman

Использование:

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

Меня устраивает.

8
Mangesh Ozardekar

На мой взгляд, это намного проще.

Получите TaskScheduler, связанный с пользовательским интерфейсом.

    var UISyncContext = TaskScheduler.FromCurrentSynchronizationContext();

Затем запустите новую задачу и на вышеупомянутом UISyncContext.

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

DispatcherTimer также опция.

Я использовал его для кода, который должен быть запущен в Xaml-конструкторе (CoreWindow.Dispatcher, ... недоступен в UWP-конструкторе)

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

Отказ от ответственности:
Я должен отметить, что это должно быть последним вариантом, если любой другой сбой.

0
David Rettenbacher

На UWP у меня возникла проблема при попытке установить свойство Source элемента управления CaptureElement (который определен в XAML), он жаловался на то, что он подготовлен в другом потоке, хотя я пытался установить его из кода, который вызывался через Page_Loaded обработчик события. Я закончил тем, что использовал это, чтобы обойти это:

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