Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

Легче напрямую получить CoreWindow из потока, отличного от UI. Следующий код будет работать везде, даже если 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;

Ответ 2

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

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

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

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

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

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

Ответ 3

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

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

Это работает для меня.

Ответ 4

Это гораздо более простой способ, на мой взгляд.

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

    var UISyncContext = TaskScheduler.FromCurrentSynchronizationContext();

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

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

Ответ 5

DispatcherTimer также является опцией.

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

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

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

Ответ 6

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

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