Как запустить код в потоке пользовательского интерфейса в WinRT (Windows 8 Metro)?
Метод Invoke
не существует.
Как запустить код в потоке пользовательского интерфейса в WinRT (Windows 8 Metro)?
Метод Invoke
не существует.
Легче напрямую получить 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;
Использование:
Из потока пользовательского интерфейса выполните:
var dispatcher = Windows.UI.Core.CoreWindow.GetForCurrentThread().Dispatcher;
Из вашего фона (без потока пользовательского интерфейса)
dispatcher.RunAsync(DispatcherPriority.Normal,
<lambda for your code which should run on the UI thread>);
Это должно работать как на CP, так и на последующих сборках.
Использование:
this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => Frame.Navigate(typeof(Welcome), this));
Это работает для меня.
Это гораздо более простой способ, на мой взгляд.
Получите TaskScheduler, связанный с пользовательским интерфейсом.
var UISyncContext = TaskScheduler.FromCurrentSynchronizationContext();
Затем запустите новую задачу и в вышеупомянутом UISyncContext.
Task.Factory.StartNew(() => { /* Do your UI stuff here; */}, new System.Threading.CancellationToken(), TaskCreationOptions.PreferFairness, UISyncContext);
DispatcherTimer также является опцией.
Я использовал его для кода, который должен быть запущен в Xaml-дизайнере (CoreWindow.Dispatcher,... не доступны в UWP-дизайнере)
var localTimer = new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(0)
};
localTimer.Tick += (timer, e) =>
{
(timer as DispatcherTimer).Stop();
action();
};
localTimer.Start();
Отказ от ответственности:
Я должен отметить, что это должно быть вариантом последнего курорта, если каждый другой не работает.
В UWP у меня возникла проблема с установкой свойства Source элемента управления CaptureElement (который определен в XAML), он жаловался на подготовку в другом потоке, хотя я пытался установить его из кода, который был вызван через обработчик события Page_Loaded. Я закончил использовать это, чтобы обойти это:
previewControl.Dispatcher.TryRunAsync(CoreDispatcherPriority.Normal, () => {
previewControl.Source = _mediaCapture;
}).GetAwaiter().GetResult();