通用窗口,c#,在应用程序初始化期间等待
本文关键字:初始化 等待 应用程序 窗口 | 更新日期: 2023-09-27 18:13:24
我正在尝试将我在Windows Phone 8上运行的一款简单应用移植到Universal Windows上。在构建主框架/页面之前,我需要加载(本地)几个文件,因为这些文件指示如何首先创建页面。有一个。xml和一些内容文件是资产的一部分。
我曾经在App.Application_Launching()期间进行初始化,我猜现在被app . onlaunching()所取代。问题是新的异步文件IO,我似乎找不到一个地方,我可以调用任何异步api而不会挂起程序。似乎在app . onlaunching (), MainPage.MainPage(), MainPage.OnNavigatedTo()等任何地方。我不能使用await
我基本上必须启动一个后台线程来安排一个任务稍后运行,以进行实际的初始化,然后回调到MainPage的池中以使某些东西正确运行。生成的代码如下所示。似乎过于复杂,但我想这是正确的?
谢谢,尼克。
public partial class MainPage : Page
{
// Constructor
public MainPage()
{
InitializeComponent();
// This doesn't work ...
// var task = InitAsync();
// task.Wait()
// This seems to ...
IAsyncAction asyncAction = ThreadPool.RunAsync((workItem) =>
{
var ignored = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
TryInitAsync();
});
});
}
private async void TryInitAsync()
{
try
{
await InitAsync();
}
catch
{
int foo = 0;
}
}
private async Task<Boolean> InitAsync()
{
// Things that go await in the night
// Other things that update the layout
return true;
}
}
似乎过于复杂,但我想这是正确的?
不,我不这么认为。
我不能提供关于初始化本身的具体建议,因为你的问题中缺少这些细节。基本策略是让UI容忍未初始化的数据,并异步运行初始化,根据需要更新属性。
就您启动异步初始化的具体方法而言,您已经使它比需要或应该的更复杂。这样会更好:
public MainPage()
{
InitializeComponent();
var ignored = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow
.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => TryInitAsync());
}
。没有必要启动ThreadPool.RunAsync()
的后台任务,如果你要做的是推迟对TryInitAsync()
方法的调用,在UI线程上调用它。
这样做(或者你更复杂的方式),你仍然阻塞UI线程。不使用Dispatcher.RunAsync()
会更好。相反,做直接从后台任务调用TryInitAsync()
(例如,用ThreadPool.RunAsync()
调用它),并使ui绑定属性依赖于初始化,随着初始化的进行异步更新。
核心概念变化是现代应用程序必须立即显示某种UI (这意味着同步)。这就是为什么你不能在启动时做I/O。 所以,在加载任何文件之前,你必须考虑你的应用应该是什么样子,立即显示这个状态,并且开始异步加载你的"真实"UI。似乎在app . onlaunching (), MainPage.MainPage(), MainPage.OnNavigatedTo()等任何地方。我不能使用await
你可以直接从构造函数中调用TryInitAsync
:
public MainPage()
{
InitializeComponent();
TryInitAsync();
}
或者,如果你能用数据绑定更新你的UI,你可以使用我的NotifyTask<T>
类型:
public NotifyTask<InitData> Data { get; }
public MainPage()
{
InitializeComponent();
Data = NotifyTask.Create(InitAsync());
}
private async Task<InitData> InitAsync() { ... }
然后你可以数据绑定到Data.Result
来获得InitData
,或者Data.IsCompleted
/Data.IsNotCompleted
来显示/隐藏初始的"loading…"状态