67

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

Invoke方法不存在。

4

6 回答 6

81

从非UI线程直接获取CoreWindow更容易。以下代码在任何地方都可以使用,即使在GetForCurrentThread()orWindow.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;
于 2013-06-26T08:32:33.343 回答
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 和更高版本的构建。

于 2012-05-15T05:02:53.663 回答
8

利用:

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

这个对我有用。

于 2012-09-14T07:32:38.667 回答
5

在我看来,这是一种更简单的方法。

获取与 UI 关联的 TaskScheduler。

    var UISyncContext = TaskScheduler.FromCurrentSynchronizationContext();

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

    Task.Factory.StartNew(() => { /* Do your UI stuff here; */}, new System.Threading.CancellationToken(), TaskCreationOptions.PreferFairness, UISyncContext);
于 2012-10-12T04:18:33.783 回答
0

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

previewControl.Dispatcher.TryRunAsync(CoreDispatcherPriority.Normal, () => {
   previewControl.Source = _mediaCapture;
}).GetAwaiter().GetResult();
于 2017-08-24T13:49:36.120 回答
0

DispatcherTimer也是一个选项。

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

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

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

于 2016-11-28T17:39:14.390 回答