我试图将我在Windows Phone 8上运行的简单应用移植到通用Windows。在构造主框架/页面之前,我需要加载(本地)一些文件,因为这些文件首先指示如何创建页面。有一个.XML和一些内容文件属于Assets。
我曾经在App.Application_Launching()期间进行初始化,我猜现在它已被App.OnLaunched()取代。问题在于新的仅异步文件IO我似乎无法找到一个可以在没有程序挂起的情况下调用任何异步API的地方。它似乎在App.OnLaunched(),MainPage.MainPage(),MainPage.OnNavigatedTo()等任何地方。我不能使用等待。
我必须基本上启动后台线程以安排任务稍后运行以进行实际初始化,然后回调到MainPage的池中以获得正确运行的内容。结果代码如下所示。看起来过于复杂,但我想这是正确的?
谢谢, 尼克。
String pattern = "a+b";
String pattern = "C__a_plus_b+d"
String pattern = "d+C__a_plus_b+F__c_plus_d"
答案 0 :(得分:1)
它似乎在App.OnLaunched(),MainPage.MainPage(),MainPage.OnNavigatedTo()等任何地方。我不能使用等待。
核心概念变化是现代应用必须显示某种UI 立即(这意味着同步)。这就是你在启动时无法进行I / O的原因。
所以,你必须考虑你的应用程序应该是什么样的之前它加载任何文件,立即显示状态,以及启动异步加载你的“真实“用户界面。
您可以直接从构造函数中调用TryInitAsync
:
public MainPage()
{
InitializeComponent();
TryInitAsync();
}
或者,如果您可以使用数据绑定更新UI,则可以使用我的NotifyTask<T>
type:
public NotifyTask<InitData> Data { get; }
public MainPage()
{
InitializeComponent();
Data = NotifyTask.Create(InitAsync());
}
private async Task<InitData> InitAsync() { ... }
然后您可以数据绑定到Data.Result
以获取InitData
,或Data.IsCompleted
/ Data.IsNotCompleted
来显示/隐藏初始“加载...”状态
答案 1 :(得分:0)
似乎过于复杂,但我想这是正确的?
不,我不会这么说。
我无法提供有关初始化本身的具体建议,因为您的问题中缺少这些详细信息。基本策略是让UI容忍未初始化的数据,并异步运行初始化,根据需要更新属性。
就你开始异步初始化的具体方法而言,你已经使它变得比它需要或应该更复杂。这会更好:
public MainPage()
{
InitializeComponent();
var ignored = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow
.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => TryInitAsync());
}
即。如果您要做的就是将您的调用推迟到ThreadPool.RunAsync()
方法,并在UI线程上调用它,则无需使用TryInitAsync()
启动后台任务。< / p>
这样做(或者更复杂的方式),你仍然在阻止UI线程。 不使用Dispatcher.RunAsync()
会更好。相反,执行直接从后台任务调用TryInitAsync()
(例如,使用ThreadPool.RunAsync()
调用它)并使UI绑定属性依赖于在初始化过程中异步更新的初始化。