在Windows应用商店应用中获取CoreDispatcher的正确方法

时间:2013-05-10 07:24:16

标签: c# windows-runtime windows-store-apps async-await dispatcher

我正在构建一个Windows应用商店应用,我有一些代码需要发布到UI线程。

为此,我想检索CoreDispatcher并使用它来发布代码。

似乎有几种方法可以这样做:

// First way
Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().CoreWindow.Dispatcher;

// Second way
Window.Current.Dispatcher;

我想知道哪一个是正确的?或两者是否相同?

5 个答案:

答案 0 :(得分:139)

这是首选方式:

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

这样做的好处是它获得了主CoreApplicationView,因此始终可用。更多详情here

您可以使用两种替代方案。

第一种选择

Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().CoreWindow.Dispatcher

这会获取应用的活动视图,但如果没有激活视图,这将为您提供 null 。更多详情here

第二种选择

Window.Current.Dispatcher

当从另一个线程调用它时,此解决方案将无效,因为它返回 null 而不是 UI Dispatcher 。更多详情here

答案 1 :(得分:12)

对于使用C ++ / CX的任何人

Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
    CoreDispatcherPriority::Normal,
    ref new Windows::UI::Core::DispatchedHandler([this]()
{
    // do stuff
}));

答案 2 :(得分:3)

await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
            CoreDispatcherPriority.Normal,
            () => { // your code should be here});

答案 3 :(得分:0)

实际上,我会提出一些建议:

boxFactory

那么,如果你打开另一个视图/窗口,你就不会让Dispatchers感到困惑......

这个小宝石检查是否有一个窗口。如果不是,请使用MainView的Dispatcher。如果有视图,请使用该视图。

答案 4 :(得分:0)

虽然这是一个旧线程,但我想提请注意开发人员可能遇到的可能影响我的问题,这使得在大型UWP应用程序中调试极为困难。就我而言,我在2014年根据上述建议重构了以下代码,但偶尔会因偶尔出现的应用冻结而感到困扰。

public static class DispatcherHelper
{
    public static Task RunOnUIThreadAsync(Action action)
    {
        return RunOnUIThreadAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, action);
    }

    public static async Task RunOnUIThreadAsync(Windows.UI.Core.CoreDispatcherPriority priority, Action action)
    {
        try
        {
            await returnDispatcher().RunAsync(priority, () =>
            {
                action();
            });
        }
        catch (Exception ex)
        {
            var noawait = ExceptionHandler.HandleException(ex, false);
        }
    }

    private static Windows.UI.Core.CoreDispatcher returnDispatcher()
    {
        return (Windows.UI.Xaml.Window.Current == null) ?
            CoreApplication.MainView.CoreWindow.Dispatcher :
            CoreApplication.GetCurrentView().CoreWindow.Dispatcher;
    }
}

从上面开始,我使用了一个静态类来允许在整个应用程序中调用Dispatcher-允许单个调用。在95%的时间内,即使通过质量检查回归,一切都很好,但是客户会不时地报告问题。解决方案是将下面的调用包括在内,而不是在实际页面中使用静态调用。

            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            { 

            });

当我需要确保从App.xaml.cs或处理推入/弹出到堆栈的Singleton NavigationService调用UI线程时,情况并非如此。当堆栈具有从MessageBus触发的各种消息时,由于每个页面都有其自己的UI线程,因此调度程序显然无法跟踪调用哪个UI线程。

希望这对可能受到影响的其他人有所帮助,也是我认为每个平台都可以通过发布涵盖最佳实践的完整项目来为开发人员提供服务的地方。