在WinRT的UI线程上运行代码
如何在WinRT(Windows 8 Metro)的UI线程上运行代码?
Invoke
方法不存在。
直接从非UI线程获取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;
使用:
在您的UI线程中,执行:
var dispatcher = Windows.UI.Core.CoreWindow.GetForCurrentThread().Dispatcher;
从你的背景(非UI线程)
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));
它适用于我。
在我看来这是一个更简单的方法。
获取与UI关联的TaskScheduler。
var UISyncContext = TaskScheduler.FromCurrentSynchronizationContext();
然后开始一个新的任务,并在上面的UISyncContext。
Task.Factory.StartNew(() => { /* Do your UI stuff here; */}, new System.Threading.CancellationToken(), TaskCreationOptions.PreferFairness, UISyncContext);
DispatcherTimer也是一个选项。
我用它的代码必须运行在Xamldevise器(CoreWindow.Dispatcher,…在UWPdevise器中不可用)
var localTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(0) }; localTimer.Tick += (timer, e) => { (timer as DispatcherTimer).Stop(); action(); }; localTimer.Start();
免责声明:
我应该注意到,如果其他的都失败了,这应该是最后的select。
在UWP上,我试图设置CaptureElement控件的Source属性(在XAML中定义的)时遇到了问题,它正在抱怨在不同的线程中准备好,即使我试图从通过Page_Loaded调用的代码中设置它事件处理器。 我最终使用这个解决方法:
previewControl.Dispatcher.TryRunAsync(CoreDispatcherPriority.Normal, () => { previewControl.Source = _mediaCapture; }).GetAwaiter().GetResult();