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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10579027/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 16:25:08  来源:igfitidea点击:

Run code on UI thread in WinRT

.netmultithreadingwindows-8windows-runtimedispatcher

提问by ofer

How can I run code on the UI thread in WinRT (Windows 8 Metro)?

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

The Invokemethod does not exist.

Invoke方法不存在。

回答by C?ur

It's easier to directly get the CoreWindowfrom the non-UI thread. The following code will work everywhere, even when GetForCurrentThread()or Window.Currentreturns null.

从非 UI 线程直接获取CoreWindow更容易。以下代码适用于任何地方,即使在GetForCurrentThread()orWindow.Current返回null 时也是如此

CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
    <lambda for your code which should run on the UI thread>);

for example:

例如:

CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
    () =>
    {
        // Your UI update code goes here!
    });

You'll need to reference Windows.ApplicationModel.Corenamespace:

您需要引用Windows.ApplicationModel.Core命名空间:

using Windows.ApplicationModel.Core;

回答by ReinstateMonica Larry Osterman

Use:

用:

From your UI thread, execute:

从您的 UI 线程,执行:

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

From your background (non UI thread)

从你的背景(非 UI 线程)

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

That should work on both CP and later builds.

这应该适用于 CP 和更高版本的构建。

回答by Mangesh Ozardekar

Use:

用:

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

It works for me.

这个对我有用。

回答by Deeb

This is a much easier way in my opinion.

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

Get the TaskScheduler associated with the UI.

获取与 UI 关联的 TaskScheduler。

    var UISyncContext = TaskScheduler.FromCurrentSynchronizationContext();

Then start a new Task and on the above UISyncContext.

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

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

回答by David Rettenbacher

DispatcherTimeris also an option.

DispatcherTimer也是一个选项。

I used it for code that must be run in Xaml-designer (CoreWindow.Dispatcher,... are not available in UWP-designer)

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

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

Disclaimer:
I should note that this should be a last-resort option if every other fails.

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

回答by George Birbilis

On UWP, I was having problem trying to set the Source property of CaptureElement control (that is defined in XAML), it was complaining about being prepared at different thread, even though I was trying to set it from code that was invoked via a Page_Loaded event handler. I ended up using this to work around it:

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

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