我正在构建Windows应用商店应用,并且我有一些代码需要发布到UI线程中。
为此,我想检索CoreDispatcher并使用它发布代码。
看来有几种方法可以这样做:
// First way
Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().CoreWindow.Dispatcher;
// Second way
Window.Current.Dispatcher;
我不知道哪一个是正确的?还是两者相等?
我正在构建Windows应用商店应用,并且我有一些代码需要发布到UI线程中。
为此,我想检索CoreDispatcher并使用它发布代码。
看来有几种方法可以这样做:
// First way
Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().CoreWindow.Dispatcher;
// Second way
Window.Current.Dispatcher;
我不知道哪一个是正确的?还是两者相等?
Answers:
这是首选方式:
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
// Your UI update code goes here!
});
这样做的好处是它成为主体CoreApplicationView,因此始终可用。更多细节在这里。
您可以使用两种替代方法。
第一种选择
Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().CoreWindow.Dispatcher
这将获取该应用程序的活动视图,但是如果未激活任何视图,它将为您提供null。更多细节在这里。
第二选择
Window.Current.Dispatcher
从另一个线程调用此解决方案将不起作用,因为它返回null而不是UI Dispatcher。更多细节在这里。
对于使用C ++ / CX的任何人
Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([this]()
{
// do stuff
}));
虽然这是一个老话题,但我想提请注意开发人员可能遇到的可能影响我的问题,这使得在大型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 Thread。
希望这对可能受到影响的其他人有所帮助,也是我认为每个平台都可以通过发布涵盖最佳实践的完整项目来为开发人员提供服务的地方。