通用窗口,c#,在应用程序初始化期间等待

时间:2016-10-18 04:09:04

标签: c# asynchronous windows-10-universal

我试图将我在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"

2 个答案:

答案 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绑定属性依赖于在初始化过程中异步更新的初始化。