在WinRT中的UI线程上运行代码

时间:2012-05-14 07:21:27

标签: .net multithreading windows-8 windows-runtime dispatcher

如何在WinRT(Windows 8 Metro)中的UI线程上运行代码?

Invoke方法不存在。

6 个答案:

答案 0 :(得分:79)

从非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;

答案 1 :(得分:69)

使用:

从您的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和后期版本。

答案 2 :(得分:8)

使用:

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

它对我有用。

答案 3 :(得分:5)

在我看来,这是一种更容易的方法。

获取与UI关联的TaskScheduler。

    var UISyncContext = TaskScheduler.FromCurrentSynchronizationContext();

然后启动一个新的Task和上面的UISyncContext。

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

答案 4 :(得分:0)

DispatcherTimer也是一种选择。

我将它用于必须在Xaml-designer中运行的代码(CoreWindow.Dispatcher,...在UWP设计器中不可用)

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

声明:
我应该注意,如果其他方法都失败,这应该是最后的选择。

答案 5 :(得分:0)

在UWP上,我在尝试设置CaptureElement控件的Source属性(在XAML中定义)时遇到问题,它抱怨在不同的线程上做好准备,即使我试图从被调用的代码设置它通过Page_Loaded事件处理程序。我最终使用它来解决它:

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