通用窗口,c#,在应用程序初始化期间等待 [英] universal windows, c#, await during app initialization

查看:20
本文介绍了通用窗口,c#,在应用程序初始化期间等待的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将我在 Windows Phone 8 上运行的简单应用程序移植到通用 Windows.在构建主框架/页面之前,我需要(本地)加载一些文件,因为这些文件首先指示如何创建页面.有一个 .XML 和一些属于 Assets 的内容文件.

I'm trying to port a simple app I had running on Windows Phone 8 to Universal Windows. I have a few files I need to load (locally) before constructing the main frame/page as those instruct how to create the page in the first place. There is a .XML and a few content files that are part of Assets.

我曾经在 App.Application_Launching() 期间进行初始化,我猜现在它被 App.OnLaunched() 取代了.问题在于新的仅异步文件 IO 我似乎找不到可以在不挂起程序的情况下调用任何异步 API 的地方.似乎在 App.OnLaunched()、MainPage.MainPage()、MainPage.OnNavigatedTo() 等中的任何地方都无法使用 await.

I used to do the initialization during the App.Application_Launching() which I guess now is replaced by App.OnLaunched(). The trouble is with the new asynchronous-only file IO I can't seem to find a place where I can call any Async APIs without the program hanging. It appears that anywhere in App.OnLaunched(), MainPage.MainPage(), MainPage.OnNavigatedTo(), etc. I can't use await.

我必须基本上启动一个后台线程来安排一个任务,以便稍后运行以进行实际的初始化,然后回调到 MainPage 的池中以使某些内容正确运行.结果代码如下所示.看起来过于复杂,但我想这是正确的吗?

I have to basically fire off a background thread to schedule a task to run later to do the actual initialization, and then call back into the MainPage's pool to get something to run correctly. The resultant code looks something like below. Seems overly complex, but I guess this is correct?

谢谢,尼克.

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;
    }
}

推荐答案

似乎在 App.OnLaunched()、MainPage.MainPage()、MainPage.OnNavigatedTo() 等中的任何地方都无法使用 await.

It appears that anywhere in App.OnLaunched(), MainPage.MainPage(), MainPage.OnNavigatedTo(), etc. I can't use await.

核心概念变化是现代应用程序必须立即(即同步)显示某种 UI.这就是你不能在启动时进行 I/O 的原因.

The core conceptual change is that modern applications must show some kind of UI immediately (which means synchronously). This is why you can't do I/O on startup.

因此,您必须在加载任何文件之前考虑您的应用应该是什么样子,立即显示该状态,并且开始异步加载您的真实"" 用户界面.

So, you have to think about what your app should look like before it loads any files, show that state immediately, and also start asynchronous loading of your "real" UI.

您可以直接从构造函数调用 TryInitAsync:

You could just call TryInitAsync directly from your constructor:

public MainPage()
{
  InitializeComponent();
  TryInitAsync();
}

或者,如果您可以使用数据绑定更新您的 UI,您可以使用我的 NotifyTask; 输入:

Or, if you can update your UI with data binding, you could use my NotifyTask<T> type:

public NotifyTask<InitData> Data { get; }
public MainPage()
{
  InitializeComponent();
  Data = NotifyTask.Create(InitAsync());
}
private async Task<InitData> InitAsync() { ... }

然后您可以将数据绑定到 Data.Result 以获取 InitDataData.IsCompleted/Data.IsNotCompleted 显示/隐藏初始正在加载..."状态.

And then you can data-bind to Data.Result to get at InitData, or Data.IsCompleted/Data.IsNotCompleted to show/hide the initial "loading..." status.

这篇关于通用窗口,c#,在应用程序初始化期间等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆